js继承(ES5,ES6)
初始化
function Person(name) {this.name = namethis.type = ["css", "js", "html"]this.sum = function () {alert(this.name)}}Person.prototype.age = 10一 原型鏈繼承(ES5)
function Per() {this.name = 'ker'}Per.prototype = new Person()var Per1 = new Per()var Per2 = new Per()Per1.type.push("vue")Per1.sum() // kerconsole.log(Per1.age) //10console.log(Per2.type) //"css","js","html","vue"//instanceof 判斷元素是否是另一個元素原型鏈上//Per1繼承了Person的屬性,返回為trueconsole.log(Per1 instanceof Person) //true優點:簡單明了
缺點:
1、新實例無法向父類構造函數傳參
2、繼承單一
3、 所有新實例都會共享父類實例屬性(一個實例修改了原型屬性,另一的原型屬性也會隨之更改)
二 借用構造函數繼承(ES5)
function Con() {Person.call(this, 'nima')}var Con1 = new Con()var Con2 = new Con()Con1.type.push("haha")console.log(Con1.age) // underfined 沒有繼承父類原型的屬性,只繼承父類構造函數的屬性console.log(Con1.name) //nimaconsole.log(Con1.type) // 'css', 'js', 'html', 'haha'console.log(Con2.type) // 'css', 'js', 'html'優點:
1、解決了子類實例共享父類引用屬性的問題
2、創建子類實例時,可以向父類構造函數傳參
缺點:
1、沒有繼承父類原型的屬性,只繼承父類構造函數的屬性
2、無法實現構造函數的復用
3、每個新實例都有父類構造函數的副本(臃腫)
三?組合繼承(ES5)
function SubType(name) {Person.call(this, name) //構造函數繼承}SubType.prototype = new Person() //原型鏈繼承var Sub = new SubType('鈴鐺')console.log(Sub.name) //鈴鐺console.log(Sub.age) // 10優點:
?1、可以繼承父類原型上的屬性,可以傳參可以復用
?2、 每一個構造函數屬性都是私有的
缺點:
用了兩次父類構造函數(耗內存),子類的構造函數會代替原型上的那個父類構造函數
四?原型式繼承(ES5)
//先封裝一個函數容器,用于輸出對象和承載繼承的原型function Conent(obj) {var f = function () { }f.prototype = obj //繼承了傳入的參數return new f() //返回函數對象}var sup = new Person('naonao') // 拿到父類的實例var sup1 = Conent(sup)console.log(sup1.name) //naonao 繼承父類函數的屬性重點: 用一個函數包裝一個對象然后返回這個函數的調用,這個函數就變成了可是隨意增添屬性的實例或對象。object.create()就是這個原理
缺點:
1、所有的實例都會繼承原型的屬性
2、無法實現復用(新實例屬性都是后面添加的)
五 寄生式繼承(ES5)
function Conent(obj) {var f = function () { }f.prototype = obj //繼承了傳入的參數return new f() //返回函數對象}var sup = new Person() // 拿到父類的實例//以上是原型式繼承,給原型式繼承再套一個殼子傳遞參數function subObject(obj) {var sub = Conent(obj)sub.name = 'yvan'return sub}var sup2 = subObject(sup) //這個函數聲明之后就成了可增添屬性的對象console.log(sup2.age) //10console.log(typeof subObject) //functionconsole.log(typeof sup2) //Object重點 :就是給原型式繼承再套一個殼子
優點:
沒有創建自定義類型,只是套了一個殼子返回對象。所以就順理成章就創建了新對象
缺點:
沒有用到原型無法復用
六:寄生組合式繼承(ES5)
function Conent(obj) { //寄生function F() { }F.prototype = objreturn new F()}var con = Conent(Person.prototype)//con實例(F實例)繼承了父類函數的原型//更像原型鏈繼承只不過繼承了原型屬性function SUb() {Person.call(this) //這個繼承了父類構造函數的屬性} //解決了組合式兩次調用構造函數屬性的缺點//重點SUb.prototype = con //繼承了con實例con.constructor = SUb // 修改實例var sub1 = new SUb()console.log(sub1.age) // 10? 特點 :修復了組合繼承的問題
ES5繼承總結:
繼承這些知識點與其說是對象的繼承,更像是函數的功能用法,如何用函數做到復用,組合,這些和使用繼承的思考是一樣的。上述幾個繼承的方法都可以手動修復他們的缺點,但就是多了這個手動修復就變成了另一種繼承模式。
ES6的繼承
class Parent {constructor (name,age){this.name = name this.age = age};tack(){console.log( '姓名:' + this.name)console.log( '年齡:' + this.age)}}class Son extends Parent{constructor (name , age ,sex){super(name,age); //super必須在子類的this之前調用this.sex = sex;}disp(){console.log('性別:' + this.sex)}zonghe(){console.log( this.name + '年齡:' + this.age +'性別:' + this.sex)}}var c1 = new Son('鬧鬧',1,'男')c1.tack() // 姓名:鬧鬧 年齡:1c1.disp() // 性別:男c1.zonghe() // 鬧鬧年齡:1性別:男重點:父類不能調用子類的方法和屬性,也就是說子類的變化不會影響到父類
es6繼承與與es5繼承的區別:
1、es5的構造函數是普通函數,可以使用關鍵詞new也可以直接用。es6的class不能當做浦東函數用必須要用new關鍵詞。
2、es5的原型方法和靜態方法可以枚舉,class默認不可枚舉,要想獲取不可枚舉屬性可以使用Object.getOwnPropertyNames方法。
3、es5的繼承,實質是先創造子類的實例對象this,再執行父類的構造函數向其添加實例方法和屬性(也可不執行),而es6的繼承機制是先創造父類的實例對象this,再用子類的構造函數修改this。
總結
以上是生活随笔為你收集整理的js继承(ES5,ES6)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HTTP:Form表单的交互与抓包
- 下一篇: JSON树节点的增删查改