在JavaScript中,将函数添加到原型和对象字面量之间的区别

26

如果我有一个构造函数 Quo

var Quo = function (string) {
     this.status = string;
};

然后使用var myQuo = new Quo("confused");创建了一个新的对象。

那么以下两种方式有何不同:

Quo.get_status = function () { 
    return this.status;
};

并且
Quo.prototype.get_status = function () { 
    return this.status;
};

1
这个答案可能有助于您理解构造函数和原型:https://dev59.com/J2Qo5IYBdhLWcg3wbe5K#16063711 - HMR
2个回答

26

假设您已经创建了myQuo,就像您所描述的那样。

var myQuo = new Quo("confused");
如果您将get_status定义为Quo的一个属性,那么要获取myQuo的状态,您需要调用Quo.get_status。但是,Quo.get_status将需要知道对象上下文(myQuo)才能返回正确的状态值。您可以重新定义该函数,接受对象作为参数,如下所示:
Quo.get_status = function (quo) { 
  return quo.status;
};
var status = Quo.get_status(myQuo);

或者你可以像在问题中所写的那样保留函数Quo.get_status,但你需要以一种将myQuo绑定到"this"的方式来调用该函数:

Quo.get_status = function() {
  return this.status;
};
var status = Quo.get_status.call(myQuo);

两种解决方案都有些不便。首选方案是利用JavaScript的原型功能,并将get_status定义为一个原型函数,该函数将对所有Quo对象(例如myQuo)本地可访问。

Quo.prototype.get_status = function () { 
  return this.status;
};
var status = myQuo.get_status();

这很有道理,我唯一困惑的是当你调用 Quo.get_status(myQuo); 时。如果函数不接受参数,你怎么能传递参数 myQuo?这是一个错误吗? - roscioli
1
@oroscioli,非常感谢您指出这一点,实际上您是无法做到的,因为我不小心忽略了这个细节。我已经相应地编辑了我的答案。 - Peter Olson
1
似乎Java中静态方法和实例方法之间的区别 - sotondolphin

22
当你定义一个函数时,它有一个叫做prototype的属性,用作使用new关键字创建的所有对象的[[prototype]]。当你向Quo.prototype添加成员时,使用new Quo()创建的所有对象都能通过它们的[[prototype]](即Quo.prototype)读取该成员。另一方面,如果直接将成员赋给Quo,你只能通过Quo本身来访问它们。
例如:
var Quo = function (status) {
    this.status = status;
}

Quo.status = "enlightened";

Quo.get_status = function() {
    return this.status;
}

Quo.prototype.get_status = function() {
    return this.status;
}

var quo = new Quo("confused");

Quo.get_status(); // "enlightened"
quo.get_status(); // "confused"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接