面向对象-继承

依次列举从基本实现到最佳方案,想看最佳方案可直接跳到页面末尾

组合继承

function  Animal() {
  this.type = 'run';
  this.classify = [1,2,1];
  this.say = function() {
    console.log(this.type);
  }
}
function Dog() {
  Animal.call(this);
}
var dog = new Dog();
dog instanceof Animal;  // false,Dog只获得了Animal的属性和方案,但在原型上没有继承关系

原型继承

function  Animal() {
  this.type = 'run';
  this.classify = [1,2,1];
  this.say = function() {
    console.log(this.type);
  }
}
function Dog() {}
Dog.prototype = new Animal;

var dog1 = new Dog();
var dog2 = new Dog();
dog1.classify.push(3);
console.log(dog2.classify);  //[1,2,1,3]
dog1.constructor;  // Animal

原型继承带来的问题:

  1. 多个实例对象指向同一个原型对象,原型对象的属性和方法共享,引用类型的属性有数据干扰问题
  2. 实例对象的constroctor被指向了Animal,而不是Dog

组合加原型继承

function  Animal() {
  this.type = 'run';
  this.classify = [1,2,1];
  this.say = function() {
    console.log(this.type);
  }
}
function Dog() {
  Animal.call(this);
}
Dog.prototype = new Animal;

问题:

  1. 实例对象的constroctor被指向了Animal,而不是Dog
  2. Animal的构造函数被执行了两次,第一次是call,第二次是new

组合加原型继承优化1

function  Animal() {
  this.type = 'run';
  this.classify = [1,2,1];
  this.say = function() {
    console.log(this.type);
  }
}
function Dog() {
  Animal.call(this);
}
Dog.prototype = Animal.prototype;

问题:实例对象的constroctor被指向了Animal,而不是Dog,此时Animal的构造函数只执行一次

组合加原型继承优化2

function  Animal() {
  this.type = 'run';
  this.classify = [1,2,1];
  this.say = function() {
    console.log(this.type);
  }
}
function Dog() {
  Animal.call(this);
}
Dog.prototype = Object.create(Animal.prototype); 
// Object.create(o),如果o是一个字面量对象或实例对象,那么相当于是实现了对象的浅拷贝
Dog.prototype.constructor = Dog;
这是最佳方案

Object.create时发生了什么?

Object.create()方法创建一个新对象,并使用现有的对象来提供新创建的对象的proto,关键代码如下

Object.create =  function (o) {
    var F = function () {};
    F.prototype = o;
    return new F();
};

Object.create(o),如果o是一个构造函数,则采用这种方法来创建对像没有意义
Object.create(o),如果o是一个字面量对象或实例对象,那么相当于是实现了对象的浅拷贝

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容