我尝试了两种方法在JS中声明一个成员函数:
function init() {
var name = "Mozilla";
function displayName() {
alert(name);
}
}
a = new init();
a.displayName()
和
function init() {
var name = "Mozilla";
displayName = function() {
alert(name);
}
}
a = new init();
a.displayName()
第一种方法告诉我displayName()
是undefined
。我创建了一个带有nae Function
的{{1}}类型变量的方式,因此它应该可以工作。
任何人都在乎解释为什么它不起作用?
由于
答案 0 :(得分:10)
它不起作用,因为现在是JavaScript的工作方式。只是在构造函数中声明一个函数不会在构造函数创建的对象上设置它,你必须明确地在对象和函数之间建立链接(直接通过将它分配给对象,或者更经常间接通过原型)。
你这样做的典型方法是通过原型继承,虽然你也可以直接将函数分配给单个对象(下面更多 - 但你谈到了“成员函数”,而你在JavaScript中做这样的事情的典型方式是通过原型)。
有几种方法可以设置原型继承。即使在传统浏览器中,与各种JavaScript引擎兼容的经典方法是通过构造函数的prototype
属性,它引用一个对象。该对象成为通过new FunctionName
创建的实例的原型。您可以向该对象添加属性,以便在该函数创建的实例之间共享它们。
所以,使用原型继承:
function Init(name) {
this.name = name;
}
Init.prototype.displayName = function() {
alert(this.name);
};
var i = new Init("Mozilla");
i.displayName();
以上注释:
在JavaScript中,压倒性的约定是构造函数以大写字母开头。所以我称之为Init
而不是init
。
所有函数都自动拥有prototype
属性,这是一个空白对象。
我向该对象添加了一个名为displayName
的属性,该对象引用了一个函数。
我没有对名称进行硬编码,而是将其作为参数传递给Init
。
请注意,我将名称存储在新构造的实例上的属性上;在Init
的调用中,该实例可用this
。
同样,因为displayName
被调用作为从对象检索函数引用的表达式的一部分,this
是调用displayName
的对象,因此{ {1}}有名字。
为了简化上述内容,我为this.name
分配了一个匿名函数。 (该属性有一个名称,函数没有。)我倾向于不在实际代码中这样做。
通过displayName
构建的所有实例都将通过原型共享new Init
函数的相同副本。
更多内容(在我的博客上):
如果您对使用JavaScript(和层次结构)构建对象类感兴趣,也可能对我的Lineage
toolkit感兴趣。
从ES5开始,还有另一种选择:Object.create
。这允许您直接创建对象并为其分配原型,而无需使用构造函数。但是当你使用displayName
时,这意味着你正在使用构造函数,我不会详细介绍它。
现在,如果你不愿意,你 不能使用JavaScript的原型功能。例如,您可以这样做:
new
这不使用JavaScript的原型功能,而是每次调用function Init(name) {
var name = name;
this.displayName = function() {
alert(name);
};
}
var i = new Init("Mozilla");
i.displayName();
时只创建一个新的displayName
函数,并将其直接分配给对象。 (任何合理质量的JavaScript引擎都足够聪明,可以重用该函数的代码,但每个实例都会有不同的函数对象)。上面的内容也使Init
属性完全私有,因为我们在每次调用时创建的函数是局部变量name
上的闭包。 (更多:Closures are not complicated)
答案 1 :(得分:6)
要创建类似成员函数的东西,您需要将它添加到构造函数的原型:
function init() {
this.name = 'Mozilla';
}
init.prototype.displayName = function() {
alert(this.name);
}
我还强烈建议您阅读有关JavaScript中的对象系统如何工作的内容。在MDN上有一篇非常好的关于它的文章:https://developer.mozilla.org/en-US/docs/JavaScript/Introduction_to_Object-Oriented_JavaScript
答案 2 :(得分:3)
以下内容应该有效:
function Init() {
var name = "Mozilla";
this.displayName = function() {
alert(name);
}
}
a = new Init();
a.displayName()
答案 3 :(得分:2)
您可以使用的标准之一是
var init = (function() {
var name = "Mozilla"; // Shared by all instances
function init() {
this.name = "IE"; // Spesific to the created instance
}
init.prototype = {
displayName: function() {
alert(name);
alert(this.name);
}
}
return init;
})();
var a = new init();
a.displayName();
答案 4 :(得分:0)
在你的第一种方法中:
function init(){ var name =“Mozilla”; function displayName(){ 警报(名); a = new init(); a.displayName()
函数displayName(){}只能在init()中调用,它就像私有函数一样,所以不能用作对象的公共函数(init())