Eva*_*hen 6 javascript ecmascript-6 es6-class
使用 # 语法,我们现在可以在 ES6 类中创建私有属性,如下所示:
class Person {
#name;
constructor(name) {
this.#name = name;
}
getName() { return this.#name; }
}
let ron = new Person('ron')
ron.#name // undefined
ron.getName(); // ron
Run Code Online (Sandbox Code Playgroud)
以前,在 ES5 中,私有属性很难通过以下方式“伪造”:
function Person(name) {
var name = name;
this.getName = function() {
return name;
}
}
(new Person('ron')).name // undefined
(new Person('ron')).getName() // ron
Run Code Online (Sandbox Code Playgroud)
上面的版本使用了“var”不属于 Person 实例的“this”这一事实。因此,使用“闭包”getName 的力量可以访问“名称”。然而,这样做的问题是 this.getName() 不是原型链的一部分,因此为了将 getName 添加到原型中,我们必须这样做:
Person.prototype.getName = function() { return this.getName(); }
Run Code Online (Sandbox Code Playgroud)
这很令人困惑,而且味道很难闻。
另一种选择是:(使用 ES6 符号但仍然不使用类)
function Person(name) {
const nameSymbol = Symbol();
this[nameSymbol] = name;
this.getName = function() {
return this[nameSymbol];
}
}
Run Code Online (Sandbox Code Playgroud)
但仍然没有解决 getName 不是原型的一部分的问题。另一个问题是,使用 Object.getOwnPropertySymbols 可以访问这个“假”私有成员。
另一个 es5 选项是使用“Revleaing 模块模式”并公开一个 publicAPI,如下所示:
const myEs5Module = (function () {
var _name = 'yos';
function getName() {
return _name;
}
const publicAPI = { getname };
return publicAPI;
})();
Run Code Online (Sandbox Code Playgroud)
但这不是一个类或构造函数,它更像是一个模块。
所以我想了解 ES6 类中私有属性的“#”语法是否是语法糖,并且可以为像我这样的函数爱好者以某种方式进行填充。
顺便说一句:我读了类似以下的文章: JavaScript ES6 类中的私有属性 ,但仍然感到不满意。另请注意:我不是在寻找 ES6 模块/babel 解决方案
ES6 类私有属性只是语法糖吗?
不。它们是对象内部工作方式的基本补充。私有字段(如它们的名称)保存在对象的新槽中,该槽在提案之前不存在,并且无法通过其他方式访问。
所以我想了解 ES6 类中私有属性的“#”语法是否是语法糖,并且可以为像我这样的函数爱好者以某种方式进行填充。
没有语法就不能使用私有属性class。(未来的提案可能会改变这一点。)相反,您必须继续做您正在做的事情(闭包解决方案),或者仅使用WeakMap您的函数有权访问由属性相关的对象作为键控的函数。
您已经完成了自己的闭包示例,因此这是Person使用该WeakMap方法而不是私有属性的类:
const Person = (() => {
const names = new WeakMap();
function Person(name) {
names.set(this, name);
}
Person.prototype.getName = function getName() {
return names.get(this);
};
return Person;
})();
let ron = new Person("ron")
console.log(ron.name); // undefined
console.log(ron.getName()); // "ron"Run Code Online (Sandbox Code Playgroud)