繼承,使子類具有父類的方法和屬性
在ES5繼承的實現非常有趣的,由于沒有傳統面向對象類的概念,Javascript利用原型鏈的特性來實現繼承。
原型鏈的特點和實現已經在之前的一篇整理說過了,就是通過將子類構造函數的原型作為父類構造函數的實例,這樣就連通了子類-子類原型-父類,原型鏈的特點就是逐層查找,從子類開始一直往上直到所有對象的原型Object.prototype,找到屬性方法之后就會停止查找,所以下層的屬性方法會覆蓋上層。
一個基本的基于**原型鏈的繼承**過程大概是這樣的:
~~~
//父類構造函數
function Plan(color){
this.color=color;
}
//父類原型加個方法
Plan.prototype.fly=function(){
console.log('flying');
}
//子類
function Fighter(){
this.bullets=[]
}
Fighter.prototype=new Plan('red')
Fighter.prototype.constructor=Fighter; //糾正constructor
Fighter.prototype.shoot=function(){ //給子類添加子類特有的方法,注意順序要在繼承之后
console.log('biu biu biu')
}
var fighter1 = new Fighter()
~~~
原型鏈實現的繼承主要有幾個問題:
1、**共享**帶來的問題,本來我們為了構造函數屬性的封裝私有性,方法的復用性,提倡將屬性聲明在構造函數內,而將方法綁定在原型對象上,但是現在子類的原型是父類的一個實例,自然父類的屬性就變成子類原型的屬性了;
這就會帶來一個問題,我們知道構造函數的原型屬性在所有構造的實例中是共享的,所以原型中屬性的改變會反應到所有的實例上,這就違背了我們想要屬性私有化的初衷;
2、創建子類的實例時,**不能**向父類的構造函數傳遞**參數**
為了解決以上兩個問題,有一個叫借用構造函數的方法
只需要在子類構造函數內部使用apply或者call來調用父類的函數即可在實現屬性繼承的同時,又能傳遞參數,又能讓實例不互相影響
3.constructor指向問題
結合借用構造函數和原型鏈的方法,可以實現比較完美的繼承方法,可以稱為**組合繼承。**
~~~
//父類構造函數
function Plan(color){
this.color=color;
}
Plan.prototype.fly=function(){
console.log('flying');
}
//子類
function Fighter(color){
Plan.call(this,color); //繼承屬性
this.bullets=[];
}
Fighter.prototype=new Plan() //繼承方法
Fighter.prototype.constructor=Fighter;
Fighter.prototype.shoot = function(){
console.log('biu biu biu');
}
var fighter1 = new Fighter('blue')
fighter1.shoot()
fighter1.fly()
~~~
還有一個**最佳實踐**,用一個函數來copy父類的方法
~~~
//父類構造函數
function Plan(color){
this.color=color;
}
Plan.prototype.fly=function(){
console.log('flying')
}
//子類
function Fighter(color){
this.bullets=[];
Plan.call(this,'red') //繼承屬性
}
inheritPrototype(Fighter,Plan) //繼承原型上的方法
//聲明inheritPrototype 方法用于繼承原型上的方法
function inheritPrototype(subType,superType){
var protoType=Object.create(superType.prototype);
protoType.constructor=subType;
subType.prototype=protoType;
}
var fighter=new Fighter()
fighter.fly()
~~~
- 以專業工程師的標準要求自己
- JS
- 函數的this
- 函數的argument
- 函數的apply、bind、call方法
- 創建對象
- 構造函數創建對象
- 原型結合構造函數創建對象
- 原型
- 繼承
- 閉包
- 正則表達式
- Ajax
- 設計模式
- ES6
- es6的模塊化
- 定義變量的新方式
- 函數擴展
- 數組擴展
- 性能與工程化
- 關于http與緩存
- 重排(reflow、layout)與重繪
- 頁面性能
- gulp
- webpack
- 一些項目回顧總結
- 移動端&微信H5游戲
- 微信小程序
- Vue.js
- 隨手記錄
- 如何通過前端技能獲取2018世界杯門票
- jsonp
- es6 javascript對象方法Object.assign()
- 一份不錯的基礎面試題
- vscode常用插件
- koroFileHeader
- 構建自己的Js工具庫
- H5 game
- Phaser從入坑到放棄再入坑
- 1.游戲的創建
- 2.資源的加載
- 3.phaser中的舞臺,世界和攝像機
- 4.游戲縮放控制,移動端的適配
- 5.phaser中的顯示對象
- 1.概述
- 2.phaser中的圖片,圖形,和按鈕
- 3.phaser中的精靈
- 4.文字
- 5.組
- 6.phaser中的動畫
- 7.粒子和瓦片地圖
- 8.瓦片地圖
- lodash
- ES5 to ESNext?—?here’s every feature added to JavaScript since 2015
- 防抖(debounce) 和 節流(throttling)