在我们的代码库中,我发现很多开发人员使用下划线作为成员变量的第一个字母来阻止公众使用。通常,更好的做法是声明一个对象方法可以访问的局部变量,但在我们的例子中,这似乎不可能,因为所有方法都是在原型上定义的。这是一个例子。
MyContrivedWidget = function(container) {
this._container = jQuery(container);
}
MyContrivedWidget.prototype = {
draw: function() {
var link = jQuery(document.createElement('a'))
.html('some contrived text')
.attr('href', '#')
.appendTo(this._container);
}
}
使用原型对象有多种原因,但最引人注目的可能是使用原型链可以轻松继承和覆盖方法。这对我们有好处,因为我们在一个平台上有多个产品,可能希望在重写特定功能的同时重用大量JavaScript。
所以我的问题是,我们怎样才能获得原型链的所有好处,而不允许公开的变量应该是公开的?
答案 0 :(得分:1)
简单地说:ECMAscript第3版不可能使用原型继承或原型链创建“私有”变量。
ES5有点不同。你有像.defineProperties()
help之类的方法,它们能够“隐藏”对象中的属性。
但是,即使你把财产隐藏起来,例如,如果他知道他们有空,那么他们仍然可以访问这些财产。正如您所提到的,ECMAland中唯一真正的隐私是调用闭包。更好地说,通过调用一个函数(-context)来使用方法模式,该函数返回一个包含方法作为属性的对象。这些方法可以访问(因为它的上下文关闭父上下文)到外部(父)范围内的声明变量。之后没有其他对象可以访问这些变量。这看起来像:
var Animal = function( args, priv, shared ) {
shared = shared || { };
shared.speed = 2;
shared.legs = 4;
shared.name = args.name || 'unknown';
priv = priv || {
run: function() {
console.log(shared.name, ' is running ', shared.speed, ' meters');
return this;
},
die: function() {
console.log(shared.name, ': wwuuaarhhhck.. aahahsd sd..aahsd.....');
return this;
}
};
return priv;
};
var Dog = function( args, priv, secret ) {
secret = secret || { };
priv = Animal( args, priv, secret ) || { };
priv.addSomeMethod = function() { };
return priv;
};
var bello = Dog({name: 'Bello'});
bello.die(); // "Bello: wwuuaarhhhck.. aahahsd sd..aahsd....."
有一些很棒的模式可以扩展这个想法,它们还提供继承和共享对象+超级方法。这种编程的良好开端仍然是Douglas Crockfords“Javascript:the good parts”。