[英]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
。 關於它沒有什么特別的或神奇的(我的意思是,語言不會對它做任何有趣的事情)。 您可以將其稱為靜態方法,因為它在所有實例中共享,但它實際上只是一個普通的屬性。 (函數是對象,對象具有屬性。)
在第二種情況下,為Test
的prototype
添加了一個新方法,使其可用於所有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.