1.在构造函数中定义私有属性或私有函数(闭包)
function Person(name,uid){
var id=uid;
this.name=name;
this.getId=function(){
return id;
}
}
var p1=new Person("zhangsan",1);
console.log(p1.name); //zhangsan
console.log(p1.id); //undefined
console.log(p1.getId()); //1
变量id只能通过特权方法getId来获取,而无法通过p1.id获取。
**优点:**每个对象的的私有属性都是独立的,不会共享(和下面的方法比)
**缺点:**每个对象上的私有方法都是独立的,不会共享,从而无法实现复用,其次无法定义所有对象共享的私有属性
2.在一个自执行的函数内定义私有属性和私有方法(闭包)
(function(){
var numberOfEyes=2;
Person=function(name){
this.name=name;
};
Person.prototype.getNumberOfEyes=function(){
return numberOfEyes;
}
})();
var p1=new Person("zhangsan");
console.log(p1.name); //zzhangsan
console.log(p1.numberOfEyes); //undefined
console.log(p1.getNumberOfEyes()); //2
在自执行的函数内部没有使用函数声明的方式(使用function functionName(){})的形式声明构造函数,而是使用函数表达式(functionName=function(){})的形式声明构造函数,因为变量前面不加var会被认为是绑定到window上的,所以在自执行函数的外部也能访问该构造函数。需要注意的是如果使用"use strict"则无法使用该方法。
**优点:**对象上的私有方法是共有的,从而避免了方法的重复声明,其次可以定义所有对象共享的私有属性
**缺点:**没法定义每个对象独有的私有属性
3.使用Symbol创建私有变量(Symol+闭包)
var Person=function(name,id){
var _id=Symbol("id");
return new function (){
this.name=name;
this._id=id;
this.getId=function(){
return this._id;
};
};
};
var p1=new Person("zhangsan",2);
console.log(p1.name); //zhangsan
console.log(p1.id); //undefined
console.log(p1.getId()); //2
每个Symbol实例都是唯一的,且由于在函数内部声明的所以只能在函数内部使用,无论p1.id还是p1._id都无法获取id的值。
**优点:**每个对象的的私有属性都是独立的,不会共享
**缺点:**无法使用instanceof来判断对象是否是Person的实例
4.使用proxy
5.使用WeakMap实现真正的私有变量
var Person=function(name,id){
var _id=Symbol("id");
var item=new WeakMap();
return new function (){
this.name=name;
item.set(this,id);
this.getId=function(){
return item.get(this);
};
};
};
var p1=new Person("zhangsan",2);
console.log(p1.name); //zhangsan
console.log(p1.id); //undefined
console.log(p1.getId()); //2
**优点:**每个对象的的私有属性都是独立的,不会共享,真正的私有变量
**缺点:**无法使用instanceof来判断对象是否是Person的实例,可读性不强,无法继承私有属性