gpt4 book ai didi

javascript - 在 JavaScript 中实现实例成员/方法

转载 作者:行者123 更新时间:2023-11-28 02:14:03 25 4
gpt4 key购买 nike

这个问题源于我试图解决的关于 JavaScript 中“私有(private)”实例变量的能力的问题。您可能想阅读this ,在我提问之前。

为了完整起见,我在提出问题之前已经说明了我的整个问题。我希望这将提供一个完整的示例,说明如何在 JavaScript 中正确实现实例成员和方法,并让任何来到这里的开发人员了解各种实现的陷阱。

考虑以下 JavaScript 对象:

var MessageBox = (function() {
function MessageBox(message) {
this.message = message;
}

MessageBox.prototype.Show = function() {
alert(this.message);
}
})();

该对象是使用 TypeScript 建模的,可以按如下方式使用:

var msg1 = new MessageBox("Hello World");
msg1.Show(); // alerts "Hello World"

var msg2 = new MessageBox("Bye World");
msg2.Show(); // alerts "Bye World"

但我仍然可以打电话:

msg1.message; // "Hello World"
msg2.message; // "Bye World"

很明显this.message不是私有(private)的。

现在考虑以下 JavaScript 对象:

var MessageBox = (function() {
return function MessageBox(message) {
var message = message;

MessageBox.prototype.Show = function() {
alert(message);
}
}
})();

这只是基于 TypeScript 的 MessageBox 对象的修改版本。

var msg1 = new MessageBox("Hello World");
msg1.Show(); // alerts "Hello World"

var msg2 = new MessageBox("Bye World");
msg2.Show(); // alerts "Bye World"

但是等等...我要在工作中扔 Spanner 了!

var msg1 = new MessageBox("Hello World");
var msg2 = new MessageBox("Bye World");
msg2.Show(); // alerts "Bye World"
msg1.Show(); // alerts "Bye World" ... wait, what!?

msg1.message // undefined
msg2.message // undefined

因此我无法再访问消息变量,但现在,每个新实例都会覆盖最后一个实例消息。

请耐心等待,这是最后一个要考虑的 JavaScript 对象:

var MessageBox = (function() {
return function MessageBox(message) {
var message = message;

this.Show = function() {
alert(message);
}
}
}();

上面的对象不再在原型(prototype)上实现 Show(),所以现在我可以:

var msg1 = new MessageBox("Hello World");
var msg2 = new MessageBox("Bye World");
msg2.Show(); // alerts "Bye World"
msg1.Show(); // alerts "Hello World"

msg1.message // undefined
msg2.message // undefined

太棒了!现在我有了私有(private)变量,并且它们不会互相覆盖!

所以,最后的问题是:以下之间有什么区别:

MessageBox.prototype.Show = function() {
}

this.Show = function() {
}

最佳答案

您最终遇到的问题有一个简单的答案:在原型(prototype)上设置函数意味着可以从任何实例调用它,而在实例上设置函数意味着只能从该实例调用它。无论哪种方式都可以访问实例上的属性,但您发现复杂的是,无论哪种方式,函数都只能访问声明它的作用域或包含作用域中的局部变量。

以下是我想到的提供私有(private)实例变量和私有(private)原型(prototype)变量的第一种方法:

var MessageBox = (function() {
var privateProtoVar = "Hello";

function MessageBox(message) {
var privateInstanceVar = message;

this.instanceMethod = function() {
alert(privateInstanceVar); // Can access private instance var
alert(privateProtoVar); // Can access private prototype var
}
}
MessageBox.prototype.Show = function() {
alert(privateProtoVar); // Can access private proto var
// but can't access privateInstanceVar
}
return MessageBox;
})();

var msg1 = new MessageBox("1"),
msg2 = new MessageBox("2");

msg1.instanceMethod(); // "1", "Hello"
msg2.instanceMethod(); // "2", "Hello"
msg1.Show(); // "Hello"
msg2.Show(); // "Hello"

变量 privateInstanceVar 可由任何在内部 MessageBox() 函数内声明的函数访问,但不能从 上的函数访问原型(prototype)除非它们在同一范围内声明(我在上面的示例中没有这样做)。

如果您稍后向实例添加其他方法,即在上述结构之外,那么这些方法将无法访问私有(private)变量,因为它们是在不同范围:

msg1.newMethod = function() {
alert(privateInstanceVar);
}
msg1.newMethod(); // error

演示:http://jsfiddle.net/SSEga/

关于javascript - 在 JavaScript 中实现实例成员/方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16688537/

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