JavaScript中的私有性
我知道,通过使用闭包和立即调用的函数,可以在JavaScript中实现“私密性” 但是如果我需要全功能的原型呢?我根本不知道在对象的原型中有私有成员。如果我使用特权方法,我可以拥有私有变量和公共方法,但我失去了原型的选择 Douglas Crockford“禁止”使用悬挂(在标识符前加下划线表示它不是公共接口的一部分) 但是使用它有那么糟糕吗?因为没有办法让它成为真正的私人JavaScript中的私有性,javascript,inheritance,prototype,closures,Javascript,Inheritance,Prototype,Closures,我知道,通过使用闭包和立即调用的函数,可以在JavaScript中实现“私密性” 但是如果我需要全功能的原型呢?我根本不知道在对象的原型中有私有成员。如果我使用特权方法,我可以拥有私有变量和公共方法,但我失去了原型的选择 Douglas Crockford“禁止”使用悬挂(在标识符前加下划线表示它不是公共接口的一部分) 但是使用它有那么糟糕吗?因为没有办法让它成为真正的私人 你对此有什么看法?您是如何处理的?您可能会感兴趣。它还讨论了模块模式。首先,在使用函数继承模式时,您不会真正失去原型效果。
你对此有什么看法?您是如何处理的?您可能会感兴趣。它还讨论了模块模式。首先,在使用函数继承模式时,您不会真正失去原型效果。我只是假设你说的是好的部分,crockford还介绍了一种非常简单有效的方法,让共享该模式的变量。基本上看起来像:
var Human = (function(my, priv) {
var my = my || {},
priv = priv || {};
my.privatedata = "foobar";
priv.walk = function() {
console.log('walking');
return priv;
};
priv.talk = function() {
console.log('blah blah');
return priv;
};
return priv;
}());
var Andy = (function(my, priv) {
var my = my || {},
priv = Human(my, priv);
priv.SpecialAndyThing = function() {
console.log('bloggin at typeofnan.com');
return priv;
};
return priv;
}());
var myAndy = Andy();
myAndy.talk().SpecialAndyThing();
您甚至可以简单地扩展此技术,使其具有某种super方法。一般来说,使用诸如下划线之类的神秘变量约定是不好的做法。这是令人困惑的,因为没有人知道那里发生了什么(如果您是唯一一个使用代码库的人,那么这个参数可能会失败)
但是,ECMAscript Edition 5引入了一些Goody,以便在原型链中拥有更多的“私有”成员。其中一个重要的方法是
.defineProperty
,您可以在其中定义一个不“浅”的属性。看起来像:
var Human = {};
Object.defineProperty(Human, 'privateStuff', {
value: 'secret',
enumerable: false
});
现在,对于从
人类
的原型链继承的对象,属性privateTuff
不可见。无论如何,这些东西需要Javascript 1.8.5,目前只在最先进的浏览器中可用。请参见以下示例,说明如何允许原型函数在所有浏览器中访问私有变量:
var Book = (function() {
var $ = {};
var Book = function(newFirst, newLast) {
// Private variables stored in an object literal.
var _ = {
author_first : newFirst,
author_last : newLast
};
// Public privileged method for accessing private variables.
this._ = function(key) {
if(key === $)
return _;
throw new Error("The _() function must be called internally.");
};
};
// Public accessor method.
Book.prototype.getAuthor = function() {
var _ = this._($);
return _.author_first + " " + _.author_last;
};
return Book;
})();
var bookA = new Book("Chris", "West"),
bookB = new Book("Douglas", "Crockford");
alert(bookA.getAuthor());
alert(bookB.getAuthor());
这与我在中实现Color类的方式相同。但是现在我为每个Human或Andy对象提供了一个单独的函数实例,不是吗?@Benjamin:是的。但这对性能或内存使用没有任何影响。“闭包和有条不紊的模式”的论点比较慢,或者诸如此类的论点在我看来是错误的。