簡體   English   中英

javascript中的構造函數和原型

[英]Constructor and prototype in javascript

這兩個代碼有什么區別,我應該使用哪一個?

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

使用Prototype:

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

第一種情況:靜態方法。

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'

第一個例子只是將一個函數賦給Test一個新屬性called method 關於它沒有什么特別的或神奇的(我的意思是,語言不會對它做任何有趣的事情)。 您可以將其稱為靜態方法,因為它在所有實例中共享,但它實際上只是一個普通的屬性。 (函數是對象,對象具有屬性。)

在第二種情況下,為Testprototype添加了一個新方法,使其可用於所有Test 實例 特殊行為。 JavaScript中的每個對象都有一個指向另一個對象的內部鏈接,稱為原型。 此鏈接是使用創建對象的構造函數的prototype建立的,因此Test創建的任何實例都將在其原型鏈中具有新屬性。

例如:

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

var a = new Test();
console.log(a.method); // => undefined

但:

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

var a = new Test();
console.log(a.method); // => function

原型方法在所有Test實例之間共享。

不會工作(例如)

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

差異可以追溯到原型鏈的工作原理。 如果您創建Test實例,那么他們將能夠訪問原型上定義的方法。

第一個代碼,只是在構造函數上添加一個“靜態”方法; 您將無法訪問該方法,執行以下操作:

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

調用該方法的唯一方法是通過構造函數引用ie

Test.method();

正如我所提到的,如果將方法添加到構造函數的原型中,則上述操作是可行的。

如果在原型中定義方法,則任何實例都可以使用該方法。 如果將方法定義為原始對象的一部分,則允許您以可合理地稱為靜態方法的方式使用該方法。

例如:

Array.isArray( [] )  //true

[].isArray() //throws a TypeError

第二個示例拋出一個TypeError因為isArray()不在Array.prototype (請記住,實例只訪問在該實例中定義的方法,或者在該實例的prototype__proto__鏈中)。

簡而言之:
*原始對象中定義的方法可以由該對象訪問,但不能訪問該對象的實例。
*原始對象的原型中定義的方法可以由原始對象的任何實例訪問。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM