私有属性作用:
- 在打印枚举对象时,只显示可能去调用的,隐藏掉背后辅助函数,免得杂乱
- 玩点花活,写一些自己才会调用,一般人不会调用的函数
- 不想被看到.
- 不想被看到. .
- 不想被看到. . .
下面我们直入主题,直接用5段代码,带你在实战中领会精髓:
1. Function
const createObject = () => {
// 私有方法
const privateMethod = () => {
console.log('这是私有方法');
return 'private result';
};
// 返回公共接口
return {
publicMethod() {
const result = privateMethod();
console.log('这是公共方法,调用了私有方法得到:', result);
}
};
};
const obj = createObject();
obj.publicMethod(); // 正常工作
obj.privateMethod(); // undefined - 无法访问
- 函数私有
- 存在的问题是无法解耦,publicMethod没法拿出来在外部定义,否则就调用不了privateMethod
2. Symbol
const privateMethod = Symbol("private");
const createObject = () => {
return {
[privateMethod]: function () {
console.log("这是私有方法");
},
publicMethod
};
};
function publicMethod() {
this[privateMethod]();
console.log('这是公共方法');
}
const obj = createObject();
console.log(obj);
obj.publicMethod(); // 正常工作
obj[privateMethod](); // 虽然技术上可行,但需要知道 privateMethod的名称
- 可以完成解耦
- 虽然光看打印内容没法调用,但如果翻找源码看到定义指向的Symbol名称,比如privateMethod,就可以通过objprivateMethod调用
- 依旧有显示,显示杂乱问题没法解决
3. DefineProperty
const createObject = () => {
const a = Math.random();
const obj = {};
// 存储私有方法
Object.defineProperty(obj, "privateMethod", {
value: ()=>console.log("privateMethod"),
// writable: true, // 是否允许修改函数,默认false
// enumerable: true, // 是否允许枚举(看到)该属性,默认false
// configurable: true, // 是否允许删除或重新定义该属性,默认false
});
// 定义公共方法
obj.publicMethod = publicMethod;
return obj;
};
function publicMethod() {
this.privateMethod();
console.log("这是公共方法");
}
const obj = createObject();
// obj.privateMethod=()=>console.log("这xxxxx法");
// delete obj.privateMethod
console.log(obj);
obj.publicMethod();
obj.privateMethod(); //虽然看不到,但若知道名称可以调用
- 可以完成解耦
- 可以隐藏显示,禁止修改,禁止删除
- 可以起到幽灵函数调用的装B效果,但反之就是还可被调用
4. WeakMap
const weakmap = new WeakMap();
const createObject = () => {
const a = Math.random();
const obj = {};
// 存储私有方法
weakmap.set(obj, {
privateMethod: () => {
console.log("这是私有方法", a);
},
});
// 定义公共方法
obj.publicMethod = publicMethod;
return obj;
};
function publicMethod() {
const private1 = weakmap.get(this);
private1.privateMethod();
console.log("这是公共方法");
}
const obj = createObject();
console.log(obj);
obj.publicMethod();
weakmap.get(obj).privateMethod(); // 虽然技术上可行,但需要访问 weakmap
const obj1 = createObject();
console.log(obj1);
obj1.publicMethod();
weakmap.get(obj1).privateMethod();
- 可以完成解耦
- 完全隐藏显示
- weakmap没被导出时,完全不可外部调用
PS : 如果是Class直接使用#定义私有属性,使用简单,不举例了