首頁  >  文章  >  web前端  >  深入了解javascript中的prototype與繼承_基礎知識

深入了解javascript中的prototype與繼承_基礎知識

WBOY
WBOY原創
2016-05-16 17:37:07904瀏覽

通常來說,javascript中的物件就是一個指向prototype的指標和一個自身的屬性清單。 javascript創建物件時採用了寫入時複製的理念。
只有建構器才有prototype屬性,原型鏈繼承就是建立一個新的指針,指向建構器的prototype屬性。
prototype屬性之所以特別,是因為javascript時讀取屬性時的遍歷機制決定的。本質上它就是一個普通的指針。

建構器包括:
1.Object
2.Function
3.Array
4.Date
5.String

下面我們來舉一些例子吧
​​

複製程式碼 程式碼>
<script> <div class="codebody" id="code33790">//每個function都有一個預設的屬性prototype,而這個prototype的constructor預設指向這個函數<BR>//注意Person.constructor 不等於Person.prototype.constructor. Function實例自帶constructor屬性<BR>   function Person(name) {  <BR>        this.name = name;  <BR>    }  <🠎>   return this.name;  <BR>    };  <BR>    var p = new Person("ZhangSan");  <BR><BR>    console.log(Person.prototype.constructor === ); .constructor === Person);  // true ,這是因為p本身不包含constructor屬性,所以這裡其實呼叫的是Person.prototype.constructor     <BR></script>




我們的目的是要表示
1.表明Person繼承自Animal2. 顯示p2是Person的實例

我們修改一下prototype屬性的指向,讓Person能取得Animal中的prototype屬性中的方法。也就是Person繼承自Animal(人是野獸)

複製程式碼

程式碼如下:<script> </script>         this.name = name; 
    }; 
    Person.prototype.getName = function() {      var p1 = new Person(" ZhangSan"); 

    console.log(p.constructor === Person);  // true 
    console.log(Person.prototype.constructor === Person);
     function Animal(){ }

     Person.prototype = new Animal();//之所以不採用Person.prototype  = Animal.prototype,是因為總結。
     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;

Person.prototype.constructor = Person;

這時>這時consturctor是對了,指向的是Person,表示p2是Person類別的實例,但出現了新問題。此時目的2達到了,目的1沒達到。

目的1和目的2此時互相矛盾,是因為此時prototype表達了矛盾的兩個意思,1表示父類是誰
2作為自己實例的原型來複製

因此我們不能直接使用prototype屬性來表示父類別是誰,而是用getPrototypeOf()方法來知道父類別是誰。





複製程式碼

程式碼如下:

Person.prototype = 新 Animal();Person.prototype = new Animal(); Person.prototype.constructor = Person;var p2 = new Person("ZhangSan");
p2.constructor     //顯示function Person() {}
Object.getPrototypeOf(Person.prototype).constructor     //顯示function Animal() {}

就把這兩個概念分開了


最後總結一下:
當程式碼var p = new Person()執行時,new 做了以下幾件事:

建立一個空白物件

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

將這個物件透過this關鍵字傳遞到建構函式中並執行建構子。

如果採用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

透過使用 hasOwnProperty()方法,何時存取的是實例屬性,何時存取的是原型屬性就 一清二楚了。
 

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn