拖了好久的JS继承终于来个总结了T^Tjavascript
本篇文章参考阮一峰老师的博文。一共有三篇。html
1、先说一下prototype对象java
function Cat(name, age){ this.name = name; this.age = age; this.speak = function () { console.log(this.name + ' miao'); } } var cat1 = new Cat('Tom', 1); var cat2 = new Cat('John', 2); console.log(cat1.speak()); // Tom miao console.log(cat2.speak()); // John miao
上面代码中的两个实例,cat1 和 cat2 都有本身的name属性,age属性,speak方法,可是其实speak方法实能够共用的,这样就会形成了资源浪费。避免这种浪费,咱们能够把 speak 方法写入构造函数的 prototype 对象中。app
function Cat(name, age){ this.name = name; this.age = age; } Cat.prototype.speak = function(){ console.log(this.name + ' miao'); } var cat1 = new Cat('Tom', 1); var cat2 = new Cat('John', 2);
将能够共享的方法挂载在原型对象上,就能够避免出现内存浪费的现象了函数
Cat.prototype.speak = function() { console.log(this.name + ' miao'); } Cat.prototype.eat = 'fish'; cat2.prototype.eat = 'meat'; // 问题来了,若是我改变其中一个实例的原型上的属性和方法,那么另外一个原型会不会收到影响呢
答案是不会!!!this
可是,若是修改的是 cat2.__proto__.eat,那么就会对 cat1 有影响了spa
这里可能有点迷!!!是的,我有点迷~~~~~~~prototype
我是这样子理解的3d
由于建立实例须要用到 new 操做符,那么 new 中间做了什么妖呢code
// 模拟 new var obj = {}; obj.__proto__ = 构造函数.prototype; 构造函数.apply(obj);
那么看会又来的构造函数 Cat,我画了这样一幅图
2、JS继承
function Animal(name){ this.name = name; } Animal.propotype = { canRun: function(){ console.log(this.name + ' can run.'); } } function Cat(){ this.speck = 'miao'; } Cat.prototype = new Animal('Tom'); Cat.prototype.constructor = Cat;
我以为应该会有人有和我同样的疑惑。为何会有Cat.prototype.constructor = Cat的出现。
由于咱们把父类Animal的实例做为了子类Cat的原型对象,所以若是没有Cat.prototype.constructor = Cat,Cat.prototype.constructor就会指向Animal,形成继承链的混乱,因此咱们须要手动纠正。
2. 构造继承——改变this的指向,用apply或者call方法实现
function Animal(name){ this.name = name; } Animal.prototype = { canRun: function(){ console.log(this.name + ' it can run!'); } } function Cat(name){ Animal.call(this, name); this.speak = 'miao'; }
var cat1 = new Cat('Tom');
这个继承方法有一个很差,就是子类没法继承父类原型上的属性和方法,也就是说 cat1.canRun()会出错。
3. 组合继承——将原型链继承和构造继承结合到一块
function Animal(name){ this.name = name; } Animal.prototype = { canRun: function(){ console.log(this.name + 'is can run!'); } } function Cat(name, age){ Animal.call(this, name); this.speak = 'miao'; this.age = age; } Cat.prototype = new Animal(); Cat.prototype.constructor = Cat; var cat1 = new Cat('Tom', 12);