在 javascript 中向原型添加函数和对象字面量之间的区别

问题描述 投票:0回答:3

如果我有一个构造函数

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;
};
javascript prototype
3个回答
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();

22
投票

定义函数时,它有一个属性

prototype
,用作它使用
[[prototype]]
关键字创建的所有对象的
new
。当您将成员添加到
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"

0
投票

需要了解实例(创建的对象)的函数应添加到“类”原型中,该原型函数分配给构造函数。

如果你这样做

instance = new Class();

然后您添加到

foo
原型中的任何函数
Class
都可以被调用为

instance.foo()

并且可以通过

instance
指针访问
this
的所有实例变量。

添加到构造函数

Class
的函数只是名为
Class
的函数对象的成员,不知道也不关心您可能创建的实例。

通常,您将常量添加到构造函数中。因此,如果您创建一个“颜色”类并添加它

Color.BLACK = 0;
(或者更好
Object.defineProperty(Color, 'BLACK', { value: 0});
) 要使其不可变,您可以像
Color.BLACK
那样访问它。

向构造函数添加函数仍然很有用。这样做就像在 Java 类中定义静态函数一样。 构造函数中主要应放置三种类型的函数:

  1. 不需要实例的通用(辅助)函数,例如

    Number.isFinite()

  2. 转换功能如

    Color.compare(color1, color2)
    。它们允许在没有实例的情况下工作。但是,他们可能会在内部创建一个实例,并可能使用原型中的实例函数。

Color.compare(color1, color2) {
    var color1 = new Color(color1);
    return color1.compare(color2);
}
  1. 特定的构造函数。虽然可以故意解释传递给构造函数的参数并确定它们的含义,但使用单独的函数来根据不同的参数创建和返回实例可能会更方便:
Color.RGB = function (r, g, b) {
    var instance = new Color();  
    instance.r = r;  
    instance.g = g;  
    instance.b = b;  
    instance.RGBtoYCC();  
    return instance;  
}  
Color.YCC = function (Y, Cr, Cb) {  
    var instance = new Color();  
    instance.Y = Y;  
    instance.Cr = Cr;  
    instance.Cb = Cb;
    instance.CYYtoRGB();  
    return instance;  
}

因此您可以创建“红色”颜色作为其中之一

var color = Color.RGB(255,0,0);

或作为

var color = Color.YCC(0.29889978, 0.5, -0.1687);
© www.soinside.com 2019 - 2024. All rights reserved.