咱們知道,JS中沒有類或接口的概念,即不能直接定義抽象的類,也不能直接實現繼承。不過,爲了編程的方便,咱們能夠在 JS 中模擬類和繼承的行爲。
首先捋清楚類和對象的關係:編程
類:好比人類,指的是一個範圍; 對象:好比某我的,指的是這個範圍中具體的對象
js中的function做爲構造函數時,就是一個類,經過new操做符,能夠返回一個對象。app
類的聲明:函數
第一種:傳統構造函數聲明
function Animal(){ this.name = 'tiger' }
第二種:ES6中的class聲明
class Animal{ constructor(){ this.name = 'tiger' } }
生成實例:
雖然類的聲明有多種方式不盡相同,可是類生成實例相同this
new Animal, new Animal2 // 沒有參數時候 ()能夠省略
類的繼承的2種方式(主要說明es5傳統構造函數的方式):es5
第一種:藉助構造函數實現繼承
<script> function Tiger(){ this.game = 'ow'; } Tiger.prototype.code=function(){ console.log('code M'); } function Child1(){ // <將構造函數Tiger的this指向子級構造函數child1的實例上> Tiger.call(this); this.type = 'child' } console.log(new Child1); </script>
原理
子類繼承父類,經過call/apply改變父類構造函數的this指向prototype
缺點
只實現了部分繼承,僅繼承了父類的屬性,並無繼承父類的原型對象上<原型鏈上>的方法code
第二種:藉助原型鏈實現繼承
<script> function Funky(){ this.friend = 'Pite'; this.arr = [1,2,3]; } Funky.prototype.dance = function(){ console.log('let us dance!!!'); } function Child2(){ this.work = 'coder'; } Child2.prototype = new Funky(); //new Child2().__proto__ === new Parent2() console.log(new Child2); var a1 = new Child2; var a2 = new Child2; a1.arr.push('666'); // 此處更改a1的arr,a2的arr也會跟着改變 console.log(a1,a2); </script>
原理
經過繼承__proto__實現原型鏈繼承:對象
1 在當前Child2實例上查找dance方法
2 發現沒有 就會去 proto 上面去找dance方法
3 Child2實例的 proto === Parent2實例
4 去Parent2實例上查找dance方法 發現沒有
5 去Parent2實例的 proto 查找dance方法
6 找到。繼承
缺點
若是實例兩個對象 改變其中一個對象的屬性/方法 另外一個對象也會跟着改變(由於改變的是原型鏈)接口