繼承有什麼好處?很簡單,繼承了你爸的財產,本身就能夠少奮鬥點嘛。開玩笑,言歸正傳,繼承使子類擁有超類的做用域、屬性與方法,能夠節省程序設計的時間。ECMAScript實現繼承主要方式是依靠原型鏈。javascript
function SuperType(){ this.colors = ["red", "blue", "green"]; } function SubType(){ } //利用原型鏈繼承 SubType.prototype = new SuperType(); var instance1 = new SubType(); console.log(instance1.colors) //["red", "blue", "green"]
上例中,經過SubType.prototype = new SuperType()
使SubType的原型鏈上增長了SuperType()這一環。從而使SubType 經過原型鏈繼承了SuperType的color
屬性。java
存在的問題:git
實例共享
在上面的例子中加入如下代碼,發現SubType()的實例1對color
屬性作出改變後,實例2獲取到的color
屬性是改變後的值。這是由於:github
每一個構造函數都有一個原型對象,原型對象都包含一個指向構造函數的指針,而實例都包含一個指向原型對象的內部指針。app
instance1.colors.push("black"); console.log(instance1.colors); //["red", "blue", "green", "black", "black"] var instance2 = new SubType(); console.log(instance2.colors);//["red", "blue", "green", "black", "black"]
function SuperType(){ this.colors = ["red", "blue", "green"]; } function SubType(){ //繼承了SuperType SuperType.call(this); } var instance1 = new SubType(); console.log(instance1.color)//["red", "blue", "green"]
基本思想即在子類型構造函數的內部調用超類型構造函數。函數
call和apply
全局函數apply和call能夠用來改變函數中this的指向。this
存在的問題:prototype
function SuperType(name){ this.name = name; this.colors = ["red", "blue", "green"]; } SuperType.prototype.sayName = function(){ console.log(this.name); }; function SubType(name, age){ //繼承屬性 SuperType.call(this, name); //第二次調用SuperType() this.age = age; } //繼承方法 SubType.prototype = new SuperType(); //第一次調用SuperType() SubType.prototype.constructor = SubType; SubType.prototype.sayAge = function(){ console.log(this.age); }; var instance1 = new SubType("Nicholas", 29); instance1.colors.push("black"); console.log(instance1.colors); //"red,blue,green,black" instance1.sayName(); //"Nicholas"; instance1.sayAge(); //29 var instance2 = new SubType("Greg", 27); console.log(instance2.colors); //"red,blue,green" instance2.sayName(); //"Greg"; instance2.sayAge();
基本思想:設計
爲何能夠實現屬性私有化?指針
存在的問題:
不管什麼狀況下,都會調用兩次超類型構造函數::一次是在建立子類型原型的時候,另外一次是在子類型構造函數內部
function object(o){ function F(){} F.prototype = o; return new F(); } var person = { name: "Nicholas", friends: ["Shelby", "Court", "Van"] }; var anotherPerson = Object.create(person); anotherPerson.name = "Greg"; anotherPerson.friends.push("Rob"); var yetAnotherPerson = Object.create(person); yetAnotherPerson.name = "Linda"; yetAnotherPerson.friends.push("Barbie"); console.log(person.friends); //["Shelby", "Court", "Van", "Rob", "Barbie"]
ECMAScript 5 經過新增Object.create()方法規範化了原型式繼承。這個方法接收兩個參數:一個用做新對象原型的對象和(可選的)一個爲新對象定義額外屬性的對象
存在同原型鏈方式同樣的問題
function object(o){ function F(){} F.prototype = o; return new F(); } function createAnother(original){ var clone = object(original); //經過調用函數建立一個新對象 clone.sayHi = function(){ //以某種方式來加強這個對象 console.log("hi"); }; return clone; //返回這個對象 } var person = { name: "Nicholas", friends: ["Shelby", "Court", "Van"] }; var anotherPerson = createAnother(person); anotherPerson.sayHi(); //"hi"
function object(o){ function F(){} F.prototype = o; return new F(); } function inheritPrototype(subType, superType){ var prototype = object(superType.prototype); //建立對象 prototype.constructor = subType; //加強對象 subType.prototype = prototype; //指定對象 } function SuperType(name){ this.name = name; this.colors = ["red", "blue", "green"]; } SuperType.prototype.sayName = function(){ console.log(this.name); }; function SubType(name, age){ SuperType.call(this, name); //調用一次SuperType() this.age = age; } inheritPrototype(SubType, SuperType); SubType.prototype.sayAge = function(){ console.log(this.age); }; var instance1 = new SubType("Nicholas", 29); instance1.sayName(); console.log(instance1.colors);
參考書籍:《javascript高級程序設計》
個人博客:http://bigdots.github.io、http://www.cnblogs.com/yzg1/
若是以爲本文不錯的話,幫忙點擊下面的推薦哦,謝謝!