javascript 私有方法中的 symbol 和 weakmap 有什么区别?
what is the difference between symbol and weakmap in javascript private methods?
我看到使用符号和弱映射在对象内创建私有成员。他们相似吗?它们都分配给对象外的 a 属性,然后在对象内被调用。
const _length=Symbol() or const _length=new Weakmap()
我很容易理解 symbol() 但是我没有得到 weakmap。在哪种情况下我应该使用 weakmap 或者我可以一直使用 symbol 吗?
以下是每种技术的完整示例:
const Foo = (() => {
const _length = Symbol('_length');
return class Foo {
[_length] = 0;
get length () { return this[_length]; }
set length (value) { this[_length] = value; }
}
})();
const bar = new Foo();
console.log(bar.length);
const Foo = (() => {
const _length = new WeakMap();
return class Foo {
constructor () { _length.set(this, 0); }
get length () { return _length.get(this); }
set length (value) { _length.set(this, value); }
}
})();
const bar = new Foo();
console.log(bar.length);
但是,Symbol
方法并不是真正的私有方法,如下所示:
const Foo = (() => {
const _length = Symbol('_length');
return class Foo {
[_length] = 0;
get length () { return this[_length]; }
set length (value) { this[_length] = value; }
}
})();
const bar = new Foo();
const _length = Object.getOwnPropertySymbols(bar)[0]; // private key exposed
console.log(bar[_length]); // private property exposed
第二种方法推荐使用 WeakMap
的原因是因为它允许 class Foo
的实例在程序中的其他任何地方不再被引用时被垃圾回收。
相比之下,普通的Map
将持有对每个实例的强引用并防止它被垃圾收集,从而导致程序内存泄漏。
现在还有第三种方法应该最终进入 ECMAScript 规范:private fields 是目前处于第 3 阶段的 TC39 class 字段提案的一部分。
class Foo {
#length = 0;
get length () { return this.#length; }
set length (value) { this.#length = value; }
}
const bar = new Foo();
console.log(bar.length);
与 Symbol
方法相反,这些是真正的私有属性。此外,它们比使用 WeakMap
.
的方法更容易编写
我看到使用符号和弱映射在对象内创建私有成员。他们相似吗?它们都分配给对象外的 a 属性,然后在对象内被调用。
const _length=Symbol() or const _length=new Weakmap()
我很容易理解 symbol() 但是我没有得到 weakmap。在哪种情况下我应该使用 weakmap 或者我可以一直使用 symbol 吗?
以下是每种技术的完整示例:
const Foo = (() => {
const _length = Symbol('_length');
return class Foo {
[_length] = 0;
get length () { return this[_length]; }
set length (value) { this[_length] = value; }
}
})();
const bar = new Foo();
console.log(bar.length);
const Foo = (() => {
const _length = new WeakMap();
return class Foo {
constructor () { _length.set(this, 0); }
get length () { return _length.get(this); }
set length (value) { _length.set(this, value); }
}
})();
const bar = new Foo();
console.log(bar.length);
但是,Symbol
方法并不是真正的私有方法,如下所示:
const Foo = (() => {
const _length = Symbol('_length');
return class Foo {
[_length] = 0;
get length () { return this[_length]; }
set length (value) { this[_length] = value; }
}
})();
const bar = new Foo();
const _length = Object.getOwnPropertySymbols(bar)[0]; // private key exposed
console.log(bar[_length]); // private property exposed
第二种方法推荐使用 WeakMap
的原因是因为它允许 class Foo
的实例在程序中的其他任何地方不再被引用时被垃圾回收。
相比之下,普通的Map
将持有对每个实例的强引用并防止它被垃圾收集,从而导致程序内存泄漏。
现在还有第三种方法应该最终进入 ECMAScript 规范:private fields 是目前处于第 3 阶段的 TC39 class 字段提案的一部分。
class Foo {
#length = 0;
get length () { return this.#length; }
set length (value) { this.#length = value; }
}
const bar = new Foo();
console.log(bar.length);
与 Symbol
方法相反,这些是真正的私有属性。此外,它们比使用 WeakMap
.