javascript中的构造函数和原型

时间:2014-02-12 19:39:16

标签: javascript

这两个代码有什么区别,我应该使用哪一个?

function Test() {}
Test.method = function() {};

使用Prototype:

function Test() {}
Test.prototype.method = function() {};

6 个答案:

答案 0 :(得分:5)

第一种情况:静态方法。

function Test() {}
Test.method = function () { alert(1); };
var t = new Test;
Test.method(); // alerts "1"
t.method(); // TypeError: Object #<Test> has no method 'method'

第二种情况:实例方法。

function Test() {}
Test.prototype.method = function () { alert(1); };
var t1 = new Test;
var t2 = new Test;
t1.method(); // alerts "1"
t2.method(); // alerts "1"
Test.method(); // TypeError: Object function Test() {} has no method 'method'

答案 1 :(得分:1)

第一个示例仅将函数分配给名为Test的{​​{1}}的新属性。关于它没有什么特别的或神奇的(我的意思是,语言不会对它做任何有趣的事情)。您可以将其称为 static 方法,因为它在所有实例中共享,但它实际上只是一个普通的属性。 (函数是对象,对象具有属性。)

在第二种情况下,method的{​​{1}}添加了一种新方法,该方法可供Test的所有实例使用。此特殊行为。 JavaScript中的每个对象都有一个指向另一个对象的内部链接,称为原型。此链接是使用创建对象的构造函数的prototype建立的,因此Test创建的任何实例都将在其原型链中具有新属性。

例如:

prototype

可是:

Test

答案 2 :(得分:0)

原型方法在Test的所有实例之间共享。

答案 3 :(得分:0)

不适用(例如)

function Test() {}
Test.method = function() {};

将起作用(例如)

function Test() {}
Test.prototype.method = function() {};

为什么?

假设您创建了一个Test实例:

t = new Test()

在调用方法时:

t.method()

JavaScript将首先在Test中查看,例如,下面将识别3个属性和方法:

function Test() {} {

    this.a = "hello";
    this.b = "world";
    this.c = function() { alert( this.a + this.b) }

}

然后第二,查找将在原型上完成:

Test.prototype.method = function() { console.log('prototype defined method') }

在JavaScript中,以下内容不会注册到实例t,而是注册Test

Test.method = function() { console.log('something unsual') };

因此

Test.method()  // works
t.method()     // no works

答案 4 :(得分:0)

差异可以追溯到原型链的工作原理。如果您创建Test实例,那么他们将能够访问原型上定义的方法。

第一个代码,只是在构造函数上添加一个“静态”方法;你将无法访问这种方法:

var testInst = new Test();
testInst.method() // Error Undefined is not a function

调用该方法的唯一方法是通过构造函数引用,即

Test.method();

正如我所提到的,如果将方法添加到构造函数的原型中,则上述操作是可行的。

答案 5 :(得分:0)

如果在原型中定义方法,则任何实例都可以使用该方法。如果将方法定义为原始对象的一部分,则允许您以可合理地称为静态方法的方式使用该方法。

例如:

Array.isArray( [] )  //true

[].isArray() //throws a TypeError

第二个示例抛出TypeError,因为isArray()不在Array.prototype中(请记住,实例仅访问在该实例中定义的方法,或者在该实例的prototype中或__proto__链)。

简而言之:
*原始对象中定义的方法可以由该对象访问,但不能访问该对象的实例 *原始对象的原型中定义的方法可以由原始对象的任何实例访问。