1.命名实现
第一个方法是使用特定的命名约定来表示属性应该被视为私有。通常以下划线作为属性名称的前缀(例如 _name )。但这并不能阻止变量被访问或修改,而是依赖于开发者之间的相互约定,认为这个变量应该被视私有属性。
class Person {
constructor(name, age) {
this._name = name;
this._age = age;
}
getName() {
return this._name;
}
setName(newName) {
this._name = newName;
}
}
const test = new Person('张三',24)
2.闭包实现
第二个方法是利用js提供的强大的闭包,闭包背后的想法是将数据封装在调用时创建的函数作用域内,但是从内部返回函数的结果,从而使这一作用域无法从外部访问。
const Person = () => {
let name = '张三';
let age = 24;
return {
getName() {
return name;
},
setName(newName) {
name = newName;
}
}
}
const test1 = Person();
test1.getName() //张三
test1.setName('李四');
test1.getName()// 李四
3.Symbol+ 闭包实现
第三个方法是利用es6提供的新特性Symbol与闭包一起使用,(如果你还不熟悉Symbol,请参阅 ECMAScript 6 入门)
const person2 = (name, age) => {
const _name = Symbol('name');
const _age = Symbol('age');
return class Person {
constructor() {
this[_name] = name;
this[_age] = age;
}
getName() {
return this[_name];
}
setName(newName) {
this[_name] = newName;
}
}
}
const Test2 = person2('张三', 24);
const test3 = new Test2();
console.log('test3', test3);
4.*Proxy + 方法一
第四个方法是利用es6提供的新特性Proxy与方法一一起使用((如果你还不熟悉Proxy,请参阅 ECMAScript 6 入门)),使用Proxy进行拦截+命名式的代码可以让这些私有变量在类外部访问受限。
const person3 = (name, age) => {
class Person {
constructor(name, age) {
this._name = name;
this._age = age;
}
getName() {
return this._name;
}
setName(newName) {
this._name = newName;
}
}
const handle = {
get(target, key) {
if (key[0] === '_') {
throw new Error('该属性为私有属性')
} else if (key === 'toJSON') {
const obj = {}
//防止JSON.stringify 序列化 如果一个被序列化的对象拥有 toJSON 方法,那么该 toJSON 方法就会覆盖该对象默认的序列化行为:不是那个对象被序列化,而是调用 toJSON 方法后的返回值会被序列化。
for (const key in target) {
if (key[0] !== '_') {
obj[key] = Reflect.get(target, key);
}
}
return obj;
}
return Reflect.get(target, key);
},
set(target, key, value) {
if (key[0] === '_') {
throw new Error('该属性为私有属性')
}
Reflect.set(target, key, value);
},
// 禁止 for in 枚举
getOwnPropertyDescriptor(target, key) {
const desc = Reflect.getOwnPropertyDescriptor(target, key);
if (key[0] === '_') {
desc.enumerable = false;
}
return desc;
}
}
return new Proxy(new Person(name, age), handle);
}
const test4 = person3('张三', 24);
test4._namr // error
JSON.stringify(test4); // {};
完整的代码实例:https://github.com/summer789/studyJS/blob/master/privateProperty.html