JavaScript极简入门教程(二):对象和函数(4)
var obj = function() {
// 隐藏 value,外部无法访问
var value = 0;
return {
// 仅此方法可以修改 value
increment: function() {
value += 1;
},
// 仅此方法可以读取 value
getValue: function() {
return value;
}
};
}();
obj.increment();
obj.getValue() === 1;
继承
JavaScript 实现继承的方式很多。
在创建对象时,我们可以设置对象关联的原型对象,我们这样做:
// 创建一个对象 o,其原型对象为 {x:1, y:2}
var o = Object.create({x:1, y:2});
Object.create 方法被定义在 ECMAScript 5 中,如果你使用 ECMAScript 3 时可以自己实现一个 create 方法:
// 如果未定义 Object.create 方法
if (typeof Object.create !== 'function') {
// 创建 Object.create 方法
Object.create = function (o) {
var F = function () {};
F.prototype = o;
// 创建一个新对象,此对象的原型对象为 o
return new F();
};
}
通过 Object.create 方法我们进行基于原型继承:一个新对象直接继承一个旧对象的属性(相对于基于类的继承,这里无需类的存在,对象直接继承对象)。范例:
var myMammal = {
name: 'Herb the Mammal',
get_name: function() {
return this.name;
},
says: function() {
return this.saying || '';
}
};
// 继承 myMammal
var myCat = Object.create(myMammal);
myCat.name = 'Henrietta';
myCat.saying = 'meow';
myCat.purr = function(n) {
var i, s = '';
for (i = 0; i < n; i += 1) {
if (s) {
s += '-';
}
s += 'r';
}
return s;
};
myCat.get_name = function() {
return this.says() + ' ' + this.name + ' ' + this.says();
};
上面的代码很简单,但是没法保护私有成员。我们可以使用模块模式。在模块模式中,某类对象由一个函数产生,并利用函数作用域保护私有成员不被外部访问:
// mammal 函数,用于构造 mammal 对象
var mammal = function(spec) {
// that 为构造的对象
var that = {};
// 公有方法 get_name 可被外部访问
that.get_name = function() {
// spec.name 外部无法直接访问
return spec.name;
};
// 公有方法 says 可被外部访问
that.says = function() {
// spec.saying 外部无法直接访问
return spec.saying || '';
};
return that;
};
// 创建 mammal 对象
var myMammal = mammal({name: 'Herb'});
// cat 函数,用于构造 cat 对象
var cat = function(spec) {
spec.saying = spec.saying || 'meow';
// cat 继承自 mammal,因此先构造出 mammal 对象
var that = mammal(spec);
// 添加公有方法 purr
that.purr = function(n) {
var i, s = '';
for (i = 0; i < n; i += 1) {
if (s) {
s += '-';
}
s += 'r';
}
return s;
};
// 修改公有方法 get_name
that.get_name = function() {
return that.says() + ' ' + spec.name +
' ' + that.says();
return that;
};
};
// 创建 cat 对象
var myCat = cat({name: 'Henrietta'});
在模块模式中,继承是通过调用构造函数来实现的。另外,我们还可以在子类中访问父类的方法: