gpt4 book ai didi

JavaScript 模块模式——私有(private)变量与静态变量

转载 作者:数据小太阳 更新时间:2023-10-29 05:07:53 33 4
gpt4 key购买 nike

所以这是著名的 JavaScript 模块模式的一个例子:

var Person = (function() {

var _name; // so called 'private variable'

function Person(name) {
_name = name;
}

Person.prototype.kill = function() {
console.log(_name + ' has been shot');
};

return Person;
})();

var paul = new Person('Paul');
paul.kill();

到目前为止还不错吧?这会将 'Paul has been shot' 记录到控制台,这正是我们想要的。

但是。

_name 真的是私有(private)变量吗?我会将私有(private)变量定义为属于对象实例的变量,外部世界无法访问它。最后一部分有效,我无法从闭包外部访问 _name

但是如果我这样做:

var paul = new Person('Paul');
var bran = new Person('Bran');
paul.kill();
bran.kill();

这将记录 'Bran has been shot',两次。那里没有保罗。所以 _name 实际上是与我的 Person 对象的所有实例共享。这就是我定义的“静态变量”,尽管它也不能从外部访问。

那么有没有办法用模块模式创建一个真正的私有(private)成员变量呢?一个不是静态的。

同样经常发生的事情是在构造函数中定义 this._name,但这会杀死私有(private)部分,现在可以从外部访问它了:

function Person(name) {
this._name = name;
}

var bran = new Person();
console.log(bran._name); // yep, accessible

问题:

所以。私有(private)并不是真正的私有(private),只是静态的。我们如何使用模块模式创建一个真正的私有(private)成员变量?一个属于实例的变量,它不是静态的,以及一个不能从外部访问的变量。

最佳答案

你是对的; _name 更像是一个静态变量。它保存在包含构造函数的闭包中,因此构造函数的每次使用都将使用相同的变量。请记住,这与类无关,而与闭包和函数有关。它可能非常方便,但这不是您处理私有(private)成员的方式。

不出所料,Douglas Crockford 有一个 page devoted to private members in Javascript .

为了成为私有(private)成员,您必须“更深入一层”。不要在构造函数之外使用闭包;使用构造函数作为闭包。构造函数内部定义的任何变量或方法显然不能被外界使用。事实上,对象也无法访问它们,因此它们非常“私有(private)”。

不过我们想使用私有(private)成员。 :) 那么怎么办?

好吧,在构造函数中,这样做:

var Klass = function () {
var private = 3;
this.privileged = function () { return private; };
};

然后:

var k = Klass();
console.log(k.privileged()); // 3

看看它是如何使用构造函数作为闭包的? this.privileged 继续存在,附加到对象,因此 privatethis.privileged 的闭包中继续存在。

不幸的是,Javascript 中的私有(private)和特权方法存在一个问题。它们每次都必须从头开始实例化。没有代码共享。这显然是我们想要的私有(private)成员,但对于方法来说并不理想。使用它们会减慢对象实例化并使用更多内存。当/如果您遇到效率问题时,请牢记这一点。

关于JavaScript 模块模式——私有(private)变量与静态变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21861677/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com