1. 程式人生 > >Javascript繼承的6種模式總結

Javascript繼承的6種模式總結

接收 基於 宋體 就是 調用 ava push property 構造函數

1、原型鏈

 1 function Supertype () {
 2   this.property = true
 3 }
 4 
 5 Supertype.prototype.getSuperValue = function () {
 6   return this.property
 7 }
 8 
 9 function SubType () {
10   this.subproperty = false
11 }
12 
13 // 繼承了SuperType
14 SubType.prototype = new Supertype()
15 
16 SubType.prototype.getSubValue = function
() { 17 return this.subproperty 18 } 19 20 var instance = new SubType() 21 console.log(instance.getSuperValue())

原型鏈的問題:

  • 共享性
  • 在創建子類型的實例時,不能向超類型的構造函數中傳遞參數

2、借用構造函數

 1 function SuperType (name) {
 2   this.name = name
 3 } 
 4 
 5 function SubType () {
 6   // 繼承了SuperType,同時還傳遞了參數
7 SuperType.call(this, ‘Nicholas‘) 8 9 // 實例屬性 10 this.age = 29 11 } 12 13 var instance = new SubType() 14 console.log(instance.name) 15 console.log(instance.age)

借用構造函數的問題:

  • 方法都在構造函數中定義
  • 無法繼承超類型的原型

3、組合繼承

組合繼承是將原型鏈和借用構造函數的技術組合到一塊,取其二者之長。

 1 function SuperType (name) {
2 this.name = name 3 this.colors = [‘red‘, ‘blue‘, ‘green‘] 4 } 5 6 SuperType.prototype.sayName = function () { 7 console.log(this.name) 8 } 9 10 function SubType (name, age) { 11 // 繼承屬性 12 SuperType.call(this, name) 13 14 this.age = age 15 } 16 17 // 繼承方法 18 SubType.prototype = new SuperType() 19 SubType.prototype.constructor = SubType 20 SubType.prototype.sayAge = function () { 21 console.log(this.age) 22 } 23 24 var instance1 = new SubType(‘Nicholas‘, 29) 25 instance1.colors.push(‘black‘) 26 console.log(instance1.colors) // "red,blue,green,black" 27 instance1.sayName() // "Nicholas" 28 instance1.sayAge() // 29 29 30 var instance2 = new SubType(‘Greg‘, 29) 31 console.log(instance2.colors) // "red,blue,green" 32 instance2.sayName() // "Greg" 33 instance2.sayAge() // 29

組合繼承避免了原型鏈和借用構造函數的缺陷,融合了它們的優點,成為Javascript中最常用的繼承模式。

4、原型式繼承

道格拉斯·克羅克福德介紹了一種實現繼承的方法,這種方法並沒有使用嚴格意義上的構造函數。他的想法是借助原型可以基於已有的對象創建對象,同時還不必因為創建自定義類型。

1 function object (o) {
2   function F() {}
3   F.prototype = o
4   return new F()        
5 }

ECMAScript 5通過新增Object.create()方法規範了原型式繼承。這個方法接收兩個參數:一個用作新對象原型的對象和(可選的)一個為新對象定義額外屬性的對象。

 1 var person = {
 2   name: ‘Nicholas‘,
 3   friends: [‘Shelby‘, ‘Court‘, ‘Van‘]
 4 }
 5 
 6 var anotherPerson = Object.create(person, {
 7   name: {
 8     value: ‘Greg‘
 9   }
10 })
11 
12 console.log(anotherPerson.name)   // "Greg"

5、寄生式繼承

1 function createAnother (original) {
2   var clone = object(original)      // 通過調用函數創建一個新對象
3   clone.sayHi = function () {       // 以某種方式來增強這個對象
4     console.log(‘hi‘)
5   } 
6   return clone                            // 返回這個對象
7 }
1 var person = {
2   name: ‘Nicholas‘,
3   friends: [‘Shelby‘, ‘Court‘, ‘Van‘]
4 }
5 
6 var anotherPerson = createAnother(person)
7 anotherPerson.sayHi()     // "Hi"

6、寄生組合式繼承

前面說過,組合繼承式JavaScript最常用的繼承模式。但它也有自己的不足,組合繼承最大的問題就是無論什麽情況下,都會調用兩次超類型構造函數:一次是在創建子類型原型的時候,另一次是在子類型構造函數內部。

 1 function SuperType (name) {
 2   this.name = name
 3   this.colors = [‘red‘, ‘blue‘, ‘green‘]
 4 }
 5 
 6 SuperType.prototype.sayName = function () {
 7   console.log(this.name)
 8 }
 9 
10 function SubType (name, age) {
11   SuperType.call(this, name)              // 第二次調用SuperType()
12   
13   this.age = age
14 }
15 
16 // 繼承方法
17 SubType.prototype = new SuperType()       // 第一次調用SuperType()
18 SubType.prototype.constructor = SubType
19 SubType.prototype.sayAge = function () {
20   console.log(this.age)
21 }

所謂寄生組合式繼承,即通過借用構造函數來繼承屬性,通過原型鏈的混成形式來繼承方法。其背後的基本思路是:不必為了指定子類型的原型而調用超類型的構造函數,我們所需要的無非就是超類型原型的一個副本而已。本質上,就是使用寄生式繼承來繼承超類型的原型,然後再將結果指定給子類型的原型。寄生組合式繼承的基本模式如下所述。

1 function inheritPrototype(subType, superType) {
2   var prototype = object(superType.prototype)   // 創建對象
3   prototype.constructor = subType              // 增強對象
4   subType.prototype = prototype                 // 指定對象
5 }
 1 function SuperType (name) {
 2   this.name = name
 3   this.colors = [‘red‘, ‘blue‘, ‘green‘]
 4 }
 5 
 6 SuperType.prototype.sayName = function () {
 7   console.log(this.name)
 8 }
 9 
10 function SubType (name, age) {
11   SuperType.call(this, name)
12 
13   this.age = age
14 }
15 
16 inheritPrototype(subType, superType)
17 
18 SubType.prototype.sayAge = function () {
19   console.log(this.age)
20 }

Javascript繼承的6種模式總結