JS對象繼承方式
摘自《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
方式三:使用call或apply方法
原理:經過改變this指向實現繼承。apply第二個參數必須是數組,call依次傳入。spa
//父類構造函數 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中建立類,最好使用構造函數定義屬性,使用原型鏈定義方法。.net
//父類構造函數 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方法
Object.create方法會使用指定的原型對象及其屬性去建立一個新的對象prototype
//父類構造函數 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自己。code
constructor指向建立此對象的函數的引用。對象
方式六:extends關鍵字實現繼承
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的構造函數。blog
super雖然表明了父類Parent的構造函數,可是返回的是子類Children的實例,即super內部的this指的是Children,所以super()在這裏至關於Parent.prototype.constructor.call(this);