91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JavaScript中是如何實現繼承的

發布時間:2020-12-07 15:04:51 來源:億速云 閱讀:193 作者:Leah 欄目:開發技術

今天就跟大家聊聊有關JavaScript中是如何實現繼承的,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。

1.原型鏈繼承

原理: 子類原型指向父類實例對象實現原型共享,即Son.prototype = new Father()。

這里先簡單介紹下原型

js中每個對象都有一個__proto__屬性,這個屬性指向的就是該對象的原型。js中每個函數都有一個prototype屬性,這個屬性指向該函數作為構造函數調用時創建的實例的原型。原型對象上有一個constructor屬性,指向創建該對象的構造函數,該屬性不可枚舉。

var obj = {};
obj.__proto__ === Object.prototype; //true
console.log(Object.prototype.constructor) // ƒ Object

當我們訪問一個對象的屬性或者方法時,如果找不到,則會通過原型向上尋找,若原型上也未找到,則會去原型的原型上面去找。比如我要調用obj.toString方法時,在自身并未找到toString方法,則會去原型上去尋找,即在Object.prototype上去尋找,找到后運行該方法。

var obj = {};
obj.toString();
obj.__proto__.toString(); //obj.__proto__和Object.prototype指向的是一個對象,自然就能訪問Object.prototype上的toString方法啦 

注意:原型鏈的終點是null,使用bind方法返回的函數沒有prototype屬性。

var obj = {};
function fn(){};
fn.bind(obj).prototype; // undefined
Object.prototype.__proto__; // null

原型鏈接繼承

function Father(age){
 this.age = age;
 this.color = ['red','pink']
}
Father.prototype.sayHello = function(){
 console.log('hello')
} 
function Son(sex){
 this.sex = sex
}
console.log(Son.prototype.constructor) // ƒ Son
Son.prototype = new Father(15) // 原型鏈繼承關鍵
var son = new Son('男')
son.color.push('black')
var son2 = new Son('女')
son.sayHello() // hello
son.sayHello === son2.sayHello //true
console.log(son2.color) // ['red','pink','black']
console.log(Son.prototype.constructor) // ƒ Father

可以看到通過原型鏈實現繼承,原型上引用類型的值會被所有實例共享。子類的constructor指向會發生改變,而且在創建子類實例時不可以向父類構造函數傳遞參數。可以手動把子類constructor屬性指回其構造函數。

//寫法一
Son.prototype.constructor = Son // 這種寫法有點缺點,它會讓constructor屬性變的可以枚舉。

//寫法二
Object.defineProperty(Son.prototype,'constructor',{
 enumerable:false, // 設置不可枚舉
 value:Son
})

2.構造函數繼承

原理:在子類構造函數中通過apply或者call調用父類構造函數來繼承屬性或方法。

function Father(name){
 this.color = ['red']
 this.sayHello = function(){
  console.log('hello')
 }
}
Father.prototype.sayName = function(){
 console.log('zs')
}
function Son(num,name){
 Father.call(this,name) //實現繼承的關鍵代碼
 this.num = num
}
var son = new Son(10,'zs')
var son2 = new Son(15,'ls')
son.color.push('pink')
console.log(son2.color) // ['red']
son.sayName() //報錯 son.sayName is not a function
console.log(son.sayHello === son2.sayHello) //false

可以看出通過構造函數實現繼承,解決了原型鏈繼承不能向父類傳參以及引用類型值共享的問題。但這種繼承方法卻不能訪問父類構造函數原型上的方法和屬性,而且定義在父類構造函數中的方法也不能復用。

3.組合式繼承

組合繼承,有時候也叫偽經典繼承,它是將原型鏈繼承和構造函數繼承結合到一起的一種繼承模式。實現思路是通過原型鏈實現對原型屬性和方法的繼承,通過借用構造函數實現對實例屬性的繼承。

function Father(name){
 this.color = ['red']
}
Father.prototype.sayName = function(){
 console.log('zs')
}
function Son(num,name){
 Father.call(this,name) //繼承實例屬性
 this.num = num
}
Son.prototype = new Father() //繼承原型上屬性
Son.prototype.constructor = Son
var son = new Son(10,'zs')
var son2 = new Son(15,'ls')
son.color.push('pink')
console.log(son.color,son2.color) //['red','pink'] ['red']
son.sayName() // zs

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

4.寄生式繼承

寄生式繼承與工廠模式類似,一般用來繼承對象。即創建一個封裝繼承的函數,在函數內部復制一份該對象,對復制的對象進行處理,返回復制的對象。

function createAnother(obj){
  var clone = Object.create(obj)
  clone.name = 'zs'
  clone.sayHello = function(){
   console.log('hello')
  }
  return clone
}
var obj = {age:15}
var newObj = createAnother(obj) // 15
console.log(newObj.name) // zs
newObj.sayHello() // hello

5.寄生組合式繼承

前面說到過組合式繼承是Javascript中最常用的繼承模式,不過這種模式也有自己的不足,它會調用兩次父類構造函數。第一次是在將子類原型指向父類實例的時候,第二次是在子類構造函數中調用的。

function Father(name){
  this.name = name
 }
 function Son(num,name){
  Father.call(this,name) // 第二次調用
 }
 Son.prototype = new Father('ls') // 第一次調用
 var son = new Son(10,'zs')
 console.log(son)

在第一次調用的時候,Son.prototype會繼承name這個屬性,第二次調用時,實例對象會繼承name。當我們獲取實例對象的name屬性時因為實例對象上有該屬性,所以是不會去原型上去尋找的,相當于實例對象上的name屬性把原型上的name屬性給屏蔽掉了,所以原型上的這個屬性是多余的。

JavaScript中是如何實現繼承的

為了解決這個問題,就有了寄生組合式繼承。主要思路就是創建一個函數完成原型鏈繼承和constructor的指向問題,然后通過構造函數繼承屬性。

 // 復制一個父類的原型指向,將子類的原型指向復制的父類原型,達到不用調用父類構造函數就能繼承其原型上的方法的效果。
 function inherit(Sup,Sub){
  var prototype = Object.create(Sup.prototype)
  Sub.prototype = prototype
  prototype.constructor = Sub
 }
 function Father(name){
  this.name = name
 }
 function Son(name){
 Father.call(this,name)
 }
 inherit(Father,Son)
 var son = new Son('zs')
 console.log(son)

JavaScript中是如何實現繼承的

看完上述內容,你們對JavaScript中是如何實現繼承的有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

铜梁县| 班玛县| 静安区| 库伦旗| 四会市| 仪陇县| 南华县| 容城县| 渭源县| 工布江达县| 安顺市| 双峰县| 湘阴县| 胶南市| 中阳县| 巴彦淖尔市| 盘锦市| 五大连池市| 南汇区| 钦州市| 和林格尔县| 新源县| 桐城市| 石棉县| 海兴县| 马尔康县| 北宁市| 孝昌县| 修文县| 保亭| 齐齐哈尔市| 眉山市| 西峡县| 武汉市| 英德市| 华宁县| 卢氏县| 神农架林区| 鸡东县| 松江区| 石林|