在es6类上创建私有成员

wea*_*e08 1 javascript ecmascript-6

我只是想知道为什么每个人都说使用WeakMap over Symbol来在javascript类中创建私有成员.

什么更好:

const NAME = new WeakMap();
class foo {
    constructor(name){
        NAME.set(this, name);
    }

    get name(){
        return NAME.get(this);
    }
}
Run Code Online (Sandbox Code Playgroud)

与:

const NAME = Symbol();
class foo {
    constructor(name){
        this[NAME] = name;
    }

    get name(){
        return this[NAME];
    }
}
Run Code Online (Sandbox Code Playgroud)

使用WeakMap可以提高速度或改善内存吗?将Symbol用于我时可以使用反射的想法将成为使用Symbol的胜利.所以我想我的问题是为什么WeakMap over Symbol?

谢谢

Ori*_*iol 5

因为符号不是私有的.如果您有对象的引用,则可以获取其符号:

var o = {};
(function trusted() {
  o[Symbol()] = "private data";
})();
o[Object.getOwnPropertySymbols(o)[0]]; // "private data" - Oops!!
Run Code Online (Sandbox Code Playgroud)

相反,如果将它们限制在受信任的闭包中,WeakMaps将无法访问:

var o = {};
(function trusted() {
  var wm = new WeakMap();
  wm.set(o, "private data");
})();
// A reference to `o` is not enough to access "private data" :D
Run Code Online (Sandbox Code Playgroud)

但是,请注意它们不是完全私密的:

var leaked;
(function attacker(_set_ = WeakMap.prototype.set) {
  WeakMap.prototype.set = function(key, value) {
    _set_.apply(this, arguments);
    leaked = value;
  };
})();
(function trusted() {
  var wm = new WeakMap();
  wm.set({}, "private data");
})();
leaked; // "private data" - Oops!!
Run Code Online (Sandbox Code Playgroud)