優雅地實現JavaScript的繼承

來源:互聯網
上載者:User

標籤:call   注意   tor   argument   nts   style   apply   世界   people   

      眾所周知,物件導向編程有三個重要的概念: 封裝、繼承、多態。而JS作為物件導向的弱類型語言,應該說是基於對象的語言,正如常說的,JS的世界裡,萬物皆對象。雖然JS本身不是物件導向的語言,我們可以通過類比的方法,來實作類別似JAVA式的類繼承。

1、建立一個自訂對象

//建構函式function People(name,age){    this.name = name;    this.age = age;}//定義原型對象People.peototype={    getName : function(){        return this.name;    },    getAge : function(){        return this.age;    }}
var p1 = new People(‘leaf‘,10);
console.log(p1.getName()) //leaf

2、當執行 var p1 = new People(‘leaf‘,10);內部主要做了這幾件事   

     1. 建立新的Null 物件(new Object());

     2. 設定新對象的__proto__繼承建構函式的prototype (p1.__proto__===People.prototype );            

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

     4. 將這個對象賦值給p1.

3、簡單的繼承,看看

建立student類,它從People繼承了原型prototype中所有的屬性。

function Student(name, age, score) {    this.name = name;    this.age = age;    this.score = score;}// 將Studen原型指向Person的一個執行個體(其實就是Student.prototype裡的__proto__指向了People的執行個體中的__proto__,
而People的執行個體中的__proto__又指向了People.prototype)。因為People的執行個體可以調用People原型中的方法, 所以Studen的執行個體也可以調用Person原型中的所有屬性。
Studen.prototype = new Person();
Student.prototype.constructor = Student;  //避免執行個體的constructor屬性指向Object函數
Studen.prototype.getScore= function() { return this.score; }; var p1 = new Employee("leaf", "12", "100"); console.log(p1.getName()); // "leaf  

4、3中的方法存在的問題

   1、在建立Student建構函式和原型時,就對Pelple進行了執行個體化,這是不合適的。
   2、Student的建構函式沒法調用父類Person的建構函式,導致在People建構函式中對name和age屬性的重複賦值。
   3、Student中的函數會覆蓋Pelple中的同名函數,沒有重載的機制.

 

5、修複之後更加優雅地繼承

//建構函式function People(name,age){    this.name = name;    this.age = age;}//定義原型對象People.prototype={    constructor : People,    getName : function(){        return this.name;    },    getAge : function(){        return this.age;    }}//定義一個Student類function Student(name,age,score){    //調用Peopel建構函式,this指向了People    People.apply(this,arguments);    this.score=score;}Student.prototype = {    constructor :Student,    getScore:function(){       return this.score;    }}//讓Student的原型對象繼承People的原型對象
Object.setPrototypeOf( Student.prototype, People.prototype);

var p2 = new Student(‘kafu‘,10,99);
console.log(p2.getScore());//99
console.log(p2.getName()); //kafu
console.log(Student.prototype.constructor==Student); //true、

  

6、總結

主要利用兩點

1、在子類型建構函式中調用父類型建構函式,改變this的指向。

注意:可以使用call(this,參數屬性)、apply(this,[參數數組])

2、利用Object.setPrototypeOf()
注意:該方法的Polyfill

Object.setPrototypeOf = Object.setPrototypeOf || function(obj, proto) {  obj.__proto__ = proto;  return obj; }

  

 

優雅地實現JavaScript的繼承

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.