本文涉及的主题虽然很基础,在许多人看来属于小伎俩,但在JavaScript基础知识中属于一个综合性的话题。这里会涉及到
对象属性的封装、原型、构造函数、闭包以及立即执行表达式
等知识。// 在构造函数中
function Person(name,age) {
this.name = name;
this.age = age;
// 公有方法
this.getName = function() {
return this.name;
}
}
// 在原型中
Person.prototype.getAge = function() {
return this.age;
}
私有方法和特权方法 这两个方法一般放在一起讨论,原因在于我们定义的特权方法是指有权访问内部私有属性和私有方法的公有方法,而私有方法是指外部不可见且不可访问的方法。
通常定义一个对象的方式有二种,一是使用Object实例化或者对象表达式,二是使用构造函数。同样在不同的方式下面定义私有方法和特权方法的形式也不相同。
在对象中
这里我们通过Object对象表达式来创建一个对象并添加一些属性和方法,然后直接采用静态的方式调用。对象的私有数据放置在一个匿名函数立即执行表达式(IIFE)中。这意味着这个函数只存在于被调用的瞬间,一旦执行后就立即被销毁了。在对象中创建私有数据的方式在对象的模式(指创建对象的模式)中被称之为模块模式,它的基本格式如下:
在模块模式中,返回的对象字面量中只包含可以公开的属性和方法。
// 私有方法
var _buyFood = function() {
_total--;
};
var _getTotal = function() {
return _total;
}
return {
name: 'McDonald',getTotal: _getTotal,buy: _buyFood
}
}) ();
Restaurant.buy();
console.log(Restaurant.name); // 'McDonald'
console.log(Restaurant.getTotal()); // 9
注意我们使用了闭包的方式来间接使用内部私有变量,同时对餐厅(Restaurant)名(name)进行了初始化。
在构造函数中
在上面介绍的模块模式创建私有方法时,公有方法和特权方法并没有什么本质上的区别,原因在于这个概念是来自于使用构造函数创建私有数据的时候定义出来的。在构造函数中定义私有属性和方法很方便,我们不需要使用闭包,可以在调用的时候初始化数据。
<div class="jb51code">
<pre class="brush:js;">
function Restaurant(name) {
// 私有属性
var _total = 10;
// 公有属性
this.name = name;
// 私有方法
function _buyFood() {
_total--;
}
// 特权方法
this.buy = function() {
_buyFood();
}
this.getTotal = function() {
return _total;
}
}
// 公有方法,注意这里不能访问私有成员_total
Restaurant.prototype.getName = function() {
console.log(_total); // Uncaught ReferenceError: _total is not defined
return this.name;
}
var McDonald = new Restaurant('McDonald');
console.log(McDonald.getName()); // 'McDonald'
McDonald.buy();
console.log(McDonald.getTotal()); // 9