轉載請註明出處:http://www.cnblogs.com/shamoyuu/p/4770235.htmlhtml
這個繼承最爲簡單,它的實現原理是,每個AO對象都有一個prototype,返回對象類型原型的引用,因此能夠給它賦值一個對象,就能夠實現簡單的原型鏈繼承。app
function Animal(){ this.eat = function(){ alert("我會吃"); } } function Bird(){ this.fly = function(){ alert("我會飛"); } } //設置Bird類的原型爲一個Animal對象 Bird.prototype = new Animal(); var pigeon = new Bird(); pigeon.fly(); pigeon.eat();
結果出現了,實現了鳥類繼承動物會吃的特性。打印一下console.info(pigeon)咱們能夠看到:函數
當前對象的__proto__屬性爲一個Animal對象,而eat方法在這個Animal對象也就是它的父類裏,若是一個屬性或方法在當前對象裏沒法找到的話,就會照着原型鏈一步一步找上去。this
這裏Bird的父類是Animal,Animal的父類是Object,或者說全部沒有直接指定prototype的對象,它的父類都是Object。由於toString()方法就是在Object裏,因此全部對象均可以調用它。而Object的父類是null。spa
還有一個須要注意的問題是,原型鏈繼承中,全部的子類的父類對象都是同一個。只要任意一個子類改變了父類對象的屬性,那全部對象都會受到影響。這點多是缺點,也多是優勢。prototype
注:prototype和__proto__的區別能夠看我另一篇博客 http://www.cnblogs.com/shamoyuu/p/prototype.html3d
原型冒充的原理是:把父類的構造函數拿過來執行一遍。下面看代碼:code
function Animal(){ this.eat = function(){ alert("我會吃"); } } function Bird(){ Animal.apply(this, arguments);this.fly = function(){ alert("我會飛"); } } var pigeon = new Bird(); pigeon.fly(); pigeon.eat();
效果跟上面是同樣同樣的,可是這個時候eat方法已經不在原型鏈上,而是在pigeon對象上。htm
複製繼承的原理是:把父類全部的屬性和方法複製過來。下面看代碼。對象
function Animal(){ this.eat = function(){ alert("我會吃"); } } function Bird(){ this.fly = function(){ alert("我會飛"); } //這裏寫一個繼承的方法,用來複制全部父類的屬性或方法 this.extend = function(parent){ for(var key in parent){ this[key] = parent[key]; } } } var pigeon = new Bird(); //執行繼承的方法 pigeon.extend(new Animal()); pigeon.fly(); pigeon.eat();
這個也和上面同樣同樣的。
ES6中引入了class的概念,新的class能幫助咱們寫出更好更直觀的面向對象的代碼。
下面這是ES6中類與類的繼承,實現的效果跟上面是同樣的。
class Animal { constructor(name){ this.name = name; this.type = "動物"; } says(say){ console.info(this.type + "【" + this.name + "】" + "說 " + say); } } let dog = new Animal("狗狗"); dog.says("汪汪汪"); class Bird extends Animal { constructor(name){ super(name); this.type = "小鳥"; } } let pigeon = new Bird("鴿子"); pigeon.says("我是一隻小鳥");
實現是很是簡單直觀的,並且不會再被人稱爲這是「模擬繼承」。
一、只能單繼承。二、繼承後會影響全部的對象。三、速度略慢。
一、雖然能夠多繼承,可是沒法在運行的時候動態繼承,只能修改父類的構造函數。
一、無。
由於上面兩個所擁有的缺點它都很好地避開了,它能夠實現多繼承,繼承隻影響當前對象,並且速度快,沒必要修改父類的構造函數等等等等,因此最推薦的仍是這種繼承方式。
注:jQuery的繼承也是採起復制繼承實現的,不過jQuery加了不少的驗證判斷,可是原理是同樣的。
若是能使用最新的ES6的特性,這種繼承是最好的,通俗易懂,是標準的面向對象的語言該有的繼承方式。
可是須要注意:
子類的contructor裏,「this」必須放在super()調用以後
子類的contructor裏必須調用super(),或者明確地返回一個對象
不能多繼承
-- Java在繼承的時候會自動生成一個父類對象,可是js裏並不會