談談javascript中的prototype與繼承

來源:互聯網
上載者:User
今天想談談javascript中的prototype.
通常來說,javascript中的對象就是一個指向prototype的指標和一個自身的屬性列表。javascript建立對象時採用了寫時複製的理念。 只有構造器才具有prototype屬性,原型鏈繼承就是建立一個新的指標,指向構造器的prototype屬性。prototype屬性之所以特別,是因為javascript時讀取屬性時的遍曆機制決定的。本質上它就是一個普通的指標。 構造器包括:
1.Object2.Function3.Array4.Date5.String
  

下面我們來舉一些例子吧

//每個function都有一個預設的屬性prototype,而這個prototype的constructor預設指向這個函數//注意Person.constructor 不等於 Person.prototype.constructor. Function執行個體內建constructor屬性   function Person(name) {         this.name = name;     };     Person.prototype.getName = function() {         return this.name;     };     var p = new Person("ZhangSan");        console.log(Person.prototype.constructor === Person); // true     console.log(p.constructor === Person);  // true ,這是因為p本身不包含constructor屬性,所以這裡其實調用的是Person.prototype.constructor   

我們的目的是要表示
1.表明Person繼承自Animal2. 表明p2是Person的執行個體
 我們修改一下prototype屬性的指向,讓Person能擷取Animal中的prototype屬性中的方法。也就是Person繼承自Animal(人是野獸)
   function Person(name) {         this.name = name;     };     Person.prototype.getName = function() {         return this.name;     };     var p1 = new Person("ZhangSan");         console.log(p.constructor === Person);  // true     console.log(Person.prototype.constructor === Person); // true      function Animal(){ }         Person.prototype = new Animal();//之所以不採用Person.prototype  = Animal.prototype,是因為new 還有其他功能,最後總結。     var p2 = new Person("ZhangSan");    //(p2 -> Person.prototype -> Animal.prototype, 所以p2.constructor其實就是Animal.prototype.constructor)          console.log(p2.constructor === Person);  // 輸出為false ,但我們的本意是要這裡為true的,表明p2是Person的執行個體。此時目的1達到了,目的2沒達到。

 

 但如果我們這麼修正 
Person.prototype = new Animal();Person.prototype.constructor = Person;
 這時p2.consturctor是對了,指向的是Person,表示p2是Person類的執行個體,但是新問題出現了。此時目的2達到了,目的1沒達到。目的1和目的2此時互相矛盾,是因為此時prototype表達了矛盾的兩個意思,
1表示父類是誰2作為自己執行個體的原型來複製
 因此我們不能直接使用prototype屬性來表示父類是誰,而是用getPrototypeOf()方法來知道父類是誰。 
    Person.prototype = new Animal();         Person.prototype.constructor = Person;         var p2 = new Person("ZhangSan");         p2.constructor     //顯示 function Person() {}         Object.getPrototypeOf(Person.prototype).constructor     //顯示 function Animal() {}

 

就把這兩個概念給分開了 ,其實通過使用 hasOwnProperty()方法,什麼時候訪問的是執行個體屬性,什麼時候訪問的是原型屬性就一清二楚了。

 new做了哪些事情?

當代碼var p = new Person()執行時,new 做了如下幾件事情:

建立一個空白對象

建立一個指向Person.prototype的指標

將這個對象通過this關鍵字傳遞到建構函式中並執行建構函式。

具體點來說,在下面這段代碼中,

  Person.prototype.getName = function() {  }

如果我們通過

var person = new Person();其實類似於var person = new Object();person.getName = Person.prototype.getName;

因此通過person.getName()調用方法時,this指向的是這個新建立的對象,而不是prototype對象。

 

這其實在給現有函數加上新功能的情況下會用到,我們可以這麼擴充現有的方法:

//function myFunc 的寫法基本上等於 var myFunc = new Function();function myFunc () {}myFunc = function(func){
  //可以在這裡做點其他事情 return function(){
     //可以在這裡做點其他事情 return func.apply(this,arguments); }}(myFunc)

 

也可以在Function.prototype方法裡直接通過this來訪問上面代碼的myFunc所指向的對象


function myFunc () {}

if (!Function.prototype.extend) { Function.prototype.extend = function(){ var func = this; return function(){ func.apply(this,arguments); } }};var myFunc = myFunc.extend();

 

 

最後總結一下:

如果採用Person.prototype  = Animal.prototype來表示Person繼承自Animal, instanceof方法也同樣會顯示p也是Animal的執行個體,返回為true.

之所以不採用此方法,是因為下面兩個原因:

1.new 建立了一個新對象,這樣就避免了設定Person.prototype.constructor = Person 的時候也會導致Animal.prototype.constructor的值變為Person,而是動態給這個新建立的對象一個constructor執行個體屬性。這樣執行個體上的屬性constructor就覆蓋了Animal.prototype.constructor,這樣Person.prototype.constructor和Animal.prototype.contructor就分開了。

2.Animal自身的this對象的屬性沒辦法傳遞給Person

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.