談到繼承,或者更廣義上的:一個對象可使用另一個對象的屬性或方法。實現起來無外乎有兩種方式:
apply or call 改變this的做用域
原型繼承 改變__proto__指向,添加做用域鏈segmentfault
而JavaScript全部的繼承實現,都是圍繞以上兩點展開的。
1.原型鏈繼承
2.構造函數繼承
3.組合繼承
4.ES6 extends 繼承babel
function Father(){} function Son(){} Son.prototype = new Father()
缺點很明顯:
子類構造函數不能傳遞參數
子類只是拷貝父類的引用,父類的引用類型的屬性會被全部的子類共享app
function Father(){} function Son(){ Father.apply(this, arguments) }
解決了參數和引用共享問題,可是父類方法不可以共享。函數
function Father(){} function Son(){ Father.apply(this, arguments) } Son.prototype = new Father()
實現了屬性分離,方法共享;es5下的完美
繼承方案this
咱們的主角,ES6 extends,就是對組合繼承的改進。不一樣的是在子類中,子類做用域和父類做用域誰先誰後的問題。es5
在ES5中,首先聲明子類的 做用域,而後在將子類的做用域指向父類prototype
在ES6中,是首先將子類的做用域指向父類,而後在此基礎上加強子類的做用域。這也是爲何在子類構造函數中必定要顯示調用super()的緣由。
參考babel轉換後的代碼:code
var Son = function (_Father) { _inherits(Son, _Person); function Son() { _classCallCheck(this, Son); //爲了方便閱讀,簡略了代碼 var _this = _possibleConstructorReturn(this,Father.call(this)); _this.gender = "male"; return _this;//返回的是 指向父類的做用域 _this } return Son; }(Father);
關於更詳細的ES6 Class的實現機制,能夠參考個人另一篇文章:聊一聊ES6 CLASS 實現原理<>對象
第一次在sifou
上發佈文章,添加了一個專題——Javascript五十問——裏面會細緻聊一些關於JavaScript原生和ES6的內容;算是我本身在開發過程當中的一點積累;若是哪位發現錯誤,但願不吝賜教,共同進步!繼承
一篇文章理解JS繼承 https://segmentfault.com/a/11...Javascript 紅寶書阮一峯 ES6標準入門