严格来讲,JavaScript没有私有成员的概念,所有对象属性都是公有的。不过,倒是有私有变量的概念,任何定义在函数或块中的变量,都可以认为是私有的,因为在这个函数或块的外部无法访问其中的变量。私有变量的包括函数参数,局部变量,以及函数内部定义的其他函数,来一起看看下面的例子:
function add(num1 num2){
let sum = num1 = num2;
return sum;
}
在这个函数中,函数add()有3个私有变量:num1,num2和sum。这几个变量只能再函数内部使用,不能在函数外部访问 如果这个函数中创建了一个闭包,则这个闭包能通过其作用域链访问其外部的这3个变量。基于这一点。就可以创建出能够访问私有变量的公有方式。
特权方法(privileged method)
是能够访问私有变量的(及私有函数)的公有方法。在对象上有两种方式创建特权方法。第一种就是在构造函数中实现:
function MyObjet(){
//私有变量和私有函数
let privateVariable = 10;
function privateFunction(){
return fails;
}
//特权方法
this.publicMethod = function(){
privateVariable++;
return privateFunction();
};
}
这个模式是把所有私有变量和私有函数都定义在构造函数中,然后,在创建一个能够访问这些私有成员的特权方法。这样做之所以可行,是因为定义在构造函数中的特权方法其实在一个闭包,他具有访问构造函数中定义的所有变量和函数的能力。在这个例子中,变量privateVariable和函数privateFunction()只能通过publicMethod()方法来访问。在创建MyObject的实例后,没有办法直接访问privateFunction()和privateVariable。唯一的办法就是使用poblicMethhod()。
下面,可以定义私有变量和特权方法,以隐藏不能被直接修改的数据
function person(name){
this.getName = finction(){
return name;
};
this.setName = function (value){
name = value;
};
}
let person = new Person('Nicholas');
console.log(person.getName()); //'Naicholas'
person.setName('Greg');
console.log(person.getName()); //'Greg'
这段代码中的构造函数定义了两个特权方法:getName()和setName()。每个方法都可以构造函数外部调用,并通过它们来读写私有的name变量。在person构造函数外部,没有别的办法访问name。因为两个方法都定义在构造函数内部,所以它们都是能够通过作用域链访问name的闭包。私有变量name对每个person实例而言都是独一无二的,因为每次调用构造函数都会重新创建一套变量和方法。不过这样也有一个问题:必须通过构造哈数来实现这种隔离。