Javascript 在es6类上创建私有成员

Javascript 在es6类上创建私有成员,javascript,ecmascript-6,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); } } 与: const NAME = Symbol(); clas

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

以下哪一点更好:

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

    get name(){
        return NAME.get(this);
    }
}
与:

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

    get name(){
        return this[NAME];
    }
}
使用WeakMap是否会提高速度或内存?当我使用符号时,反射可用的想法将是使用符号的胜利。所以我想我的问题是,为什么符号上的弱映射


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

var o = {};
(function trusted() {
  o[Symbol()] = "private data";
})();
o[Object.getOwnPropertySymbols(o)[0]]; // "private data" - Oops!!
相反,如果您将weakmap限制在受信任的闭包中,则无法访问它们:

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
但是,请注意,它们也不是完全隐私的:

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!!

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

var o = {};
(function trusted() {
  o[Symbol()] = "private data";
})();
o[Object.getOwnPropertySymbols(o)[0]]; // "private data" - Oops!!
相反,如果您将weakmap限制在受信任的闭包中,则无法访问它们:

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
但是,请注意,它们也不是完全隐私的:

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!!

对,我将Object.getOwnPropertySymbols等同于反射,因此在我看来它们仍然是私有的,就像C#/Java成员可以标记为私有一样。就像您可以在C#或Java中使用反射来设置私有成员一样,我认为您在javascript中也可以这样做没有问题。这是否是私人会员不愿使用符号的主要原因?@weagle08我认为这是主要原因。嗯,对于非自有对象,有些人可能认为在其中存储数据在道德上是错误的。对,我将Object.getOwnPropertySymbols等同于反射,因此在我看来,它们仍然是私有的,就像C#/Java成员可以标记为私有的一样。就像您可以在C#或Java中使用反射来设置私有成员一样,我认为您在javascript中也可以这样做没有问题。这是否是私人会员不愿使用符号的主要原因?@weagle08我认为这是主要原因。嗯,对于非自有对象,有些人可能认为在其中存储数据在道德上是错误的。