摘要:前記在維基百科中繼承的含義是使子類別具有父類別的屬性和方法,或者說子類構造的對象直接擁有父類對象的屬性。但是在中并沒有子類和父類的概念,也沒有類和實例的區分,的繼承是靠原型鏈來實現的。
前記
在維基百科中繼承的含義是使子類別具有父類別的屬性和方法,或者說子類構造的對象直接擁有父類對象的屬性。
但是在JavaScript中并沒有"子類"和"父類"的概念,也沒有"類"(class)和"實例"(instance)的區分,JavaScript的繼承是靠prototype(原型鏈)來實現的。
prototype繼承實現我曾寫過一篇名為原型和原型鏈的文章,那時候說明了原型和原型鏈是什么,那繼承只要在它的原型鏈中添加公有屬性就可以了
假如我們寫一個構造函數Human
function Human(name){ this.name = name//構造函數可以生成新對象,this就是這個新對象 }
然后在Human的原型鏈上添加函數run
Human.prototype.run = function (){ console.log(this.name + "在跑") return undefined }
這樣當我們用Human構造一個對象時候
let a = new Human("lgm") //Human {name: "lgm"} // name: "lgm"/ // __proto__: // run: ? () // constructor: ? Human(name) // __proto__: Object
現在我們再寫一個構造函數Man
function Man(name){ this.name = name//this新生成的對象 this.gender: "男"http://this新生成的對象 }
然后在Man的原型鏈上添加函數fight
Man.prototype.fight = function (){ console.log(this.name + "會打架") }
這樣用Man構造一個對象就是
let b = new Man("lgm") //Man {name: "lgm"} // name: "lgm"/ // gender: "男" // __proto__: // fight: ? () // constructor: ? Man(name) // __proto__: Object
當我們想要Man繼承Human的屬性的時候,就可以知道,只要
Man.prototype.__proto__ = Human.prototype
修改Man
function Man(name){ Human.call(this, name) this.gender: "男"http://this新生成的對象 }
就可以完成繼承了,讓我們來試一下
再次構造一個Man對象
let lgm = new Man("lgm") //Man {name: "lgm", gender: "男"} // gender: "男" // name: "lgm"/ // __proto__: Human // fight: ? () // constructor: ? Man(name) // __proto__: // run: ? () // constructor: ? Human(name) // __proto__: Object
由此我們可以看到,Man繼承了Human中的run()函數,但是有一個問題
直接操作__proto__是不屬于ECMA規范的,在IE中直接操作并不可行,我們需要換一種寫法
var f = function(){} f.prototype = Human.prototype Man.prototype = new f()
這樣是使用了new的特性,讓我們來試一下,然后再次構造一個Man對象
let lgm = new Man("lgm") //Man {name: "lgm", gender: "男"} // gender: "男" // name: "lgm"/ // __proto__: Human // fight: ? () // __proto__: // run: ? () // constructor: ? Human(name) // __proto__: Object
可以看到,效果是一樣的
class語法糖在ES6語法中,新增了一個叫做class的語法,專門用來實現繼承,上面代碼通過class改寫如下
class Human { constructor(name) { this.name = name } run() { console.log("我叫" + this.name + ",我在跑") return undefined } } class Man extends Human {//Man.prototype.__proto__ = Human.prototype constructor(name) { super(name)//Human.call(this, name) this.gender = "男" } fight() { console.log(this.name + "會打架") } }兩種方法的優劣
prototype繼承寫法麻煩,但是簡單易懂,而class繼承的寫法雖然簡單,但難以理解
并且,原型鏈繼承添加繼承屬性的話會會非常簡單,只需
Human.prototype.headNumber = "1"
而class繼承如果需要添加繼承屬性會非常麻煩
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/97590.html
摘要:此用來定義通過構造器構造出來的對象的原型,構造器內部的代碼用來給對象初始化。 對象繼承 VS 類繼承 在 class-based 的面向對象的世界里,要出現對象,必須先有類。類之間可以繼承,類再使用 new 操作創建出實體,父子對象之間的繼承體現在父類和子類上。你不能說 對象 a 繼承了對象 b,只能說 class A 繼承了 class B,然后他們各自有一個實例a、b。 JS中實現...
摘要:首先捋清楚類和對象的關系類比如人類,指的是一個范圍對象比如某個人,指的是這個范圍中具體的對象中的作為構造函數時,就是一個類,通過操作符,可以返回一個對象。 JS中的類與類的繼承 我們知道,JS中沒有類或接口的概念,即不能直接定義抽象的類,也不能直接實現繼承。不過,為了編程的方便,我們可以在 JS 中模擬類和繼承的行為。首先捋清楚類和對象的關系: 類:比如人類,指的是一個范圍; ...
摘要:的繼承方式屬于原型式繼承,非常靈活。當使用關鍵字執行類的構造函數時,系統首先創建一個新對象,這個對象會繼承自構造函數的原型對象新對象的原型就是構造函數的屬性。也就是說,構造函數用來對生成的新對象進行一些處理,使這個新對象具有某些特定的屬性。 繼承這個東西在Javascript中尤其復雜,我掌握得也不好,找工作面試的時候在這個問題上栽過跟頭。Javascript的繼承方式屬于原型式繼承,...
摘要:對象經典對象創建與繼承模式組合模式創建對象中創建一個對象的方式多種多樣,每種方式都有自己缺點或者優點,具體的可以參考而組合使用構造函數模式和原型模式來創建自定義類型算是最常見的方式了。 title: JS對象(3)經典對象創建與繼承模式 date: 2016-09-28 tags: JavaScript 0x01 組合模式創建對象 JS 中創建一個對象的方式多種多樣,...
摘要:原型對象是由創建的,因此原型對象的構造函數是構造函數也可以是稱為對象,原型對象也就繼承了其生父構造函數中的數據,也同時繼承了原型對象的數據。當然這條原型鏈中的數據,會被還是還是這類構造函數繼承,但是不會被這些繼承,他們不處于同一個鏈條上。 js中,Function的本質是什么?Object的本質又是什么?js中有幾條原型鏈? showImg(https://segmentfault.c...
閱讀 826·2021-11-22 11:59
閱讀 3230·2021-11-17 09:33
閱讀 2308·2021-09-29 09:34
閱讀 1941·2021-09-22 15:25
閱讀 1955·2019-08-30 15:55
閱讀 1321·2019-08-30 15:55
閱讀 530·2019-08-30 15:53
閱讀 3346·2019-08-29 13:55