JavaScript中實現繼承的幾種方式的使用和分析

首先來看一段代碼:

  1. function Person(){
  2. }
  3. function Student(){
  4. }
  5. Student.prototype = Person.prototype;//第一種方式
  6. Student.prototype = new Person();//第二種方式
  7. Student.prototype = Object.create(Person.prototype)//第三種方式

第一種方式(不可取)

    可以實現繼承,但是在改變Student的同時也會相應的改變Person,這很顯然不是我們所需要的,所以此種繼承方案不可取,是錯誤的。

第二種方式(原型繼承)

    new Person()調用構造函數得到了一個Person的實例,並且這個實例指向了Person的prototype,所以這裏實現了繼承。但是就是因爲調用了構造函數,所以這樣可能會有問題,比如說,Person的構造函數是需要傳遞參數的function Person(name,age)等,那麼在實例化的時候需要傳遞什麼參數進去呢?很顯然,不管傳遞什麼都是很彆扭的,所以此種方案使用的也不多。

第三種方式(Object.ceate):

    此方案是最爲理想的方案。使用Object.create()方法創建一個空的對象,並且這個對象的原型指向了Person.prototype,這樣我們既保證了我們可以繼承Person.prototype上面的方法,並且Student.prototype又有自己的一個空的對象,所以Student的修改不會影響到原型鏈上面的方法。

    但是這裏也有一個問題,就是Object.create()方法是在ES5之後纔有的方法,那麼在之前的版本我們可以用另一個方法來模擬一下代替:

  1. if(!Object.create){
  2. Object.create = function(proto){
  3. funtion F(){} //臨時的空函數
  4. F.prototype = proto; //將空函數的prototype屬性複製給我們想要作爲原型的對象
  5. return new F; //new一個構造器,那麼就會創建一個對象,這個對象的原型指向構造器的prototype
  6. }
  7. }


另外還有一種方式,使用call和apply:

  1. function Person(name,age,love){
  2. this.name=name;
  3. this.age=age;
  4. this.love=love;
  5. this.say=function say(){
  6. alert("姓名:"+name);
  7. }
  8. }
  9. //call方式
  10. function student(name,age){
  11. Person.call(this,name,age);
  12. }
  13. //apply方式
  14. function teacher(name,love){
  15. Person.apply(this,[name,love]);
  16. //Person.apply(this,arguments); //跟上句一樣的效果,arguments
  17. }
  18. //call與aplly的異同:
  19. //1,第一個參數this都一樣,指當前對象
  20. //2,第二個參數不一樣:call的是一個個的參數列表;apply的是一個數組(arguments也可以)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章