是否可以在ES6类中创建私有属性?
举个例子。 如何阻止访问instance.property?
class Something {
constructor(){
this.property = "test";
}
}
var instance = new Something();
console.log(instance.property); //=> "test"
是否可以在ES6类中创建私有属性?
举个例子。 如何阻止访问instance.property?
class Something {
constructor(){
this.property = "test";
}
}
var instance = new Something();
console.log(instance.property); //=> "test"
当前回答
现在大多数浏览器都支持私有类特性。
class Something {
#property;
constructor(){
this.#property = "test";
}
#privateMethod() {
return 'hello world';
}
getPrivateMessage() {
return this.#property;
}
}
const instance = new Something();
console.log(instance.property); //=> undefined
console.log(instance.privateMethod); //=> undefined
console.log(instance.getPrivateMessage()); //=> test
console.log(instance.#property); //=> Syntax error
其他回答
这取决于你问谁:-)
最大最小类提案中没有包含私有属性修饰符,这似乎已经进入了当前的草案。
但是,可能会支持私有名称,它允许私有属性—而且它们可能也可以用于类定义中。
我现在听到的建议是使用WeakMaps来保存私人数据,以供其他看客参考。
下面是一个更清晰、有效的例子:
function storePrivateProperties(a, b, c, d) {
let privateData = new WeakMap;
// unique object as key, weak map can only accept object as key, when key is no longer referened, garbage collector claims the key-value
let keyA = {}, keyB = {}, keyC = {}, keyD = {};
privateData.set(keyA, a);
privateData.set(keyB, b);
privateData.set(keyC, c);
privateData.set(keyD, d);
return {
logPrivateKey(key) {
switch(key) {
case "a":
console.log(privateData.get(keyA));
break;
case "b":
console.log(privateData.get(keyB));
break;
case "c":
console.log(privateData.get(keyC));
break;
case "d":
console.log(privateData.set(keyD));
break;
default:
console.log(`There is no value for ${key}`)
}
}
}
}
我相信在构造函数中使用闭包是可能获得“两全其美”的。有两种变化:
所有数据成员都是私有的
函数myFunc() { console.log(' x的值:' + this.x); this.myPrivateFunc (); } 函数myPrivateFunc() { console.log(' x的增强值:' +(此。X + 1)); } 类测试{ 构造函数(){ Let internal = { X: 2, }; 内部的。myPrivateFunc = myPrivateFunc.bind(内部); 这一点。myFunc = myFunc.bind(内部); } };
有些成员是私有的
注意:这确实很难看。如果您知道更好的解决方案,请编辑此回复。
function myFunc(priv, pub) { pub.y = 3; // The Test object now gets a member 'y' with value 3. console.log('Value of x: ' + priv.x); this.myPrivateFunc(); } function myPrivateFunc() { pub.z = 5; // The Test object now gets a member 'z' with value 3. console.log('Enhanced value of x: ' + (priv.x + 1)); } class Test { constructor() { let self = this; let internal = { x : 2, }; internal.myPrivateFunc = myPrivateFunc.bind(null, internal, self); this.myFunc = myFunc.bind(null, internal, self); } };
WeakMap
IE11支持(符号不支持) hard-private(由于Object.getOwnPropertySymbols,使用符号的道具是soft-private) 看起来非常干净(不像闭包需要构造函数中的所有道具和方法)
首先,定义一个函数来包装WeakMap:
function Private() {
const map = new WeakMap();
return obj => {
let props = map.get(obj);
if (!props) {
props = {};
map.set(obj, props);
}
return props;
};
}
然后,在类外部构造一个引用:
const p = new Private();
class Person {
constructor(name, age) {
this.name = name;
p(this).age = age; // it's easy to set a private variable
}
getAge() {
return p(this).age; // and get a private variable
}
}
注意:IE11不支持class,但在示例中它看起来更简洁。
是的-你可以创建封装的属性,但它没有与访问修饰符(公共|私有)至少不是与ES6。
下面是一个简单的例子,如何用ES6完成:
用类词创建类
2在构造函数内部使用let OR const保留字声明块作用域变量->因为它们是块作用域,所以不能从外部访问(封装)
为了允许对这些变量进行一些访问控制(setter |getter),你可以在它的构造函数中使用:this.methodName=function(){}语法声明实例方法
"use strict";
class Something{
constructor(){
//private property
let property="test";
//private final (immutable) property
const property2="test2";
//public getter
this.getProperty2=function(){
return property2;
}
//public getter
this.getProperty=function(){
return property;
}
//public setter
this.setProperty=function(prop){
property=prop;
}
}
}
现在让我们检查一下:
var s=new Something();
console.log(typeof s.property);//undefined
s.setProperty("another");//set to encapsulated `property`
console.log(s.getProperty());//get encapsulated `property` value
console.log(s.getProperty2());//get encapsulated immutable `property2` value