大家可能知道ES11已经从官方规范上实现了“私有”的概念,不管是私有属性还是私有方法都只需要在前面加上“#“即可,但是ES11版本太新,担心可能很多浏览器不能很好的支持,并不是所有用户都会使用Chrome,对吧? 所以这一次我们从ES5开始到ES6实现私有化的概念
一、ES5闭包
'use strict'
//第一种
const Test=function(){
//定义私有属性
let privateAttr;
function Test(id){
privateAttr="我是私有属性"
this.publicAttr="我是对象公有属性";
privateFun=privateFun.bind(this); //改变私有方法this指向
}
//私有方法
function privateFun(){
console.log(privateAttr); //访问私有变量
console.log(this.publicAttr); //访问对象属性
}
return Test;
}();
const t=new Test();
console.log(t.publicAttr); //我是对象公有属性
console.log(t.privateAttr); //undefined
console.log(t.privateFun); //undefined
看到这,如果你就是想访问publicAttr的值,不妨在Test原型上添加一个”特权方法“,将私有变量的值返回出去即可。
二、ES6 Symbol
'use strict'
const Test=function(){
const privateAttr = Symbol('private');
const privateFun = Symbol('private');
function Test(){
this[privateAttr]=9;
this.attr=1;
this[privateFun](); //调用私有方法
}
Test.prototype.add=function(){
this[privateAttr]=this[privateAttr]+1;
console.log(`私有属性+1得到的结果${this[privateAttr]}`);
this.attr=this.attr+1;
console.log(`对象属性+1得到的结果${this.attr}`);
}
Test.prototype[privateFun]=function(){
console.log("这里是私有方法");
console.log(`私有属性是${this[privateAttr]}`);
}
return Test;
}();
const t=new Test(); //这里是私有方法 私有属性是9
t.add(); //私有属性+1得到的结果10 对象属性+1得到的结果2
privateAttr privateFun 的值都是 Symbol('private'),但是他们内部得到的引用不一样,这就是Symbol的好处,使用Symbol 使得私有方法也能在原型上定义,避免了不必要的this指向问题,这个方法优于上面的方法
三、ES6?WeakMap和Symbol
'use strict'
const Test=function(){
const wm=new WeakMap();
function Test(){
this.attr="对象属性";
this.privateAttr=Symbol('private');
this.privateFun=Symbol('private');
const privateMem=wm.get(this) || {};
privateMem[this.privateAttr]="private Attribute";
privateMem[this.privateFun]=privateFun.bind(this);
wm.set(this,privateMem);
}
function privateFun(){
wm.get(this)[this.privateAttr]="new private Attribute";
console.log(`改变后私有变量的值是 ${wm.get(this)[this.privateAttr]}`);
console.log(`对象属性 ${this.attr}`);
}
Test.prototype.show=function(){
console.log(`私有属性的值: ${wm.get(this)[this.privateAttr]}`);
wm.get(this)[this.privateFun](); //调用私有方法
}
return Test;
}();
const t=new Test();
t.show();
//私有属性的值: private Attribute
//改变后私有变量的值是 new private Attribute
//对象属性 对象属性
|