摘自《JavaScript的對象繼承方式,有幾種寫法》,做者:peakedness
連接:http://www.javashuo.com/article/p-zmgddvlv-hz.html數組
原理:構造函數使用this關鍵字給全部屬性和方法賦值(即採用類聲明的構造函數方式)。由於構造函數只是一個函數,因此可以使Parent構造函數稱爲Children的方法,而後調用它。Children會收到Parent的構造函數中定義的屬性和方法。
***app
//父類構造函數 var Parent = function(name){ this.name = name; this.sayHi = function(){ console.log("Hi" + this.name + "."); } } var Children = function(name){ this.method = Parent; this.method(name); //實現繼承 delete this.method; this.getName = function(){ console.log(this.name); } } var P = new Parent("john"); var C = new Children("joe"); P.sayHi(); //Hi john C.sayHi(); //Hi joe C.getName(); //joe
原理:JS是一門基於原型的語言。在JS中prototype對象的任何屬性和方法都被傳遞給那個類的全部實例。函數
//父類構造函數 var Parent = function(name){ this.name = name; this.sayHi = function(){ console.log("Hi" + this.name + "."); } } //子類構造函數 var Children = function(){}; Children.prototype = new Parent(); var P = new Parent(); var C = new Children(); P.sayHi(); C.sayHi();
注意:
調用Parent的構造函數,沒有給它傳遞參數。這是原型鏈中的標準作法,要確保構造函數沒有任何參數。this
原理:經過改變this指向實現繼承。apply第二個參數必須是數組,call依次傳入。.net
//父類構造函數 var Parent = function(name){ this.name = name; this.sayHi = function(){ console.log("Hi" + this.name + "."); } }; //子類構造函數 var Children = function(name){ Parent.call(this,name); this.getName = function(){ console.log(this.name); } }; var C = new Children("Joe"); C.sayHi(); //Hi john C.getName(); //Joe
使用原型鏈就沒法使用帶參數的構造函數了
所以,在JS中建立類,最好使用構造函數定義屬性,使用原型鏈定義方法。prototype
//父類構造函數 var Parent = function(name){ this.name = name; } Parent.prototype.sayHi = function(){ console.log("Hi ! " + this.name + "!!!"); } var P = new Parent("John"); P.sayHi(); //Hi John !!!
Object.create方法會使用指定的原型對象及其屬性去建立一個新的對象code
//父類構造函數 var Parent = function(name){ this.name = name; } Parent.prototype.sayHi = function(){ console.log("Hi " + this.name + "."); } //子類構造函數 var Children = function(name,age){ this.age = age; Parent.call(this,name); //屬性不在prototype上 }; Children.prototype = Object.create(Parent.prototype); Children.prototype.constructor = Children; Children.prototype.getAge = function(){ console.log(this.age); }; var P = new Parent("John"); var C = new Children("Joe",30); P.sayHi(); //Hi John C.sayHi(); //Hi Joe C.getAge(); //30
注意:
當執行Children.prototype = Object.create(Parent.prototype)這個語句後,Children的constructor就被變爲Parent,所以須要將Children.protype.constructor從新指定爲Children自己。對象
constructor指向建立此對象的函數的引用。blog
class Paren{ constructor(name,age){ this.name = name; this.age = age; } } class Children extends Parent{ constructor(name,age,job){ super(name,age); //super必須在前,不然代碼報錯 this.job = job; } }
注意:
子類的constructor方法沒有調用super以前,就使用this關鍵字會報錯。緣由是:子類Children的構造函數之中的super(),表明調用父類Parent的構造函數。繼承
super雖然表明了父類Parent的構造函數,可是返回的是子類Children的實例,即super內部的this指的是Children,所以super()在這裏至關於Parent.prototype.constructor.call(this);