JavaScript ES6 inherintance会杀死类中的属性吗?

时间:2018-01-22 00:40:47

标签: javascript class variables inheritance privacy

这是非常基本的代码示例:

"use strict";

class aClass {
    readFromA() {
        console.log(this.a);
    }


    constructor() {
        this.a = 5;
    }
}

class bClass extends aClass {
    readFromB() {
        console.log(this.a);
    }


    constructor() {
        super();
        this.a = 10;
    }
}

let bc = new bClass();
bc.readFromA(); //10
bc.readFromB(); //10

我的目的是在JS中使用最现代的对象编程技术。 ES6引入了它们的类和继承。它似乎是无用的编程风格。例如,上面的代码用bClass中相同的变量名覆盖类aClass中的属性“a”。 。 让我们假设2个proggramers创建这些类。他们每个人都不知道将使用哪些变量名称。如果他们都使用相同的变量名称 - 它将导致灾难!这两个类都会读写相同的属性,导致应用程序崩溃。如何保护类中的属性以防止覆盖并能够利用“扩展”功能?

2 个答案:

答案 0 :(得分:2)

  

他们每个人都不知道将使用哪些变量名称。如果他们都使用相同的变量名称 - 它将导致灾难!

这当然是一种非常糟糕的做法。你不应该继承你不了解的课程,而且每个课程都应该为了这个目的记录其公共成员。

  

如何保护班级中的属性,防止覆盖并且能够利用"扩展"功能?

不要使用相同的密钥。如果您无法使用正确的文档或命名约定来确保这一点,那么symbols就可以解决这个问题。

const a = Symbol("a");
export default class {
    constructor() {
        this[a] = 5;
    }
    readFromA() {
        console.log(this[a]);
    }
}

import ClassA from '…';

const a = Symbol("a"); // a different symbol than that in the AClass module
class BClass extends AClass {
    constructor() {
        super();
        this.a = 10;
        this[a] = 15;
    }
    readFromB() {
        console.log(this.a, this[a]);
    }
}

const x = new BClass();
x.readFromA(); // 5
x.readFromB(); // 10, 15

答案 1 :(得分:0)

与此同时,我找到了解决上面提到的私有属性问题的方法。 Bergi的想法得以实施。这是代码:

"use strict";


let aClass = (function () {
let a = Symbol("a");

class aClass {
    readFromA() {
        console.log(this[a], this.b);
    }

    constructor() {
        this[a] = "aaa"; //this is private
        this.b="bbb"; // this is public
    }

}

return aClass;
})();

let bClass = (function () {
let a = Symbol("a");

class bClass extends aClass {
    readFromB() {
        console.log(this[a], this.b);
    }

    constructor() {
        super();
        this[a] = "ccc"; //this is private
        this.b="ddd"; // this is public
    }

}

return bClass;
})();

let bc=new bClass();
bc.readFromA();
bc.readFromB();

结果是: aaa ddd ccc ddd

由于封装,我在两个类中使用相同的属性名称“a”进行管理,每个类都接收不同的值。属性“b”是公开的,可以覆盖。使用这种方法,我们不必在两个类中都使用属性名称。不存在意外覆盖基类的非公共属性的风险。 此外,这种封装允许以传统方式使用类的继承:通过“extends”关键字。