javascript高级程序设计的几种经典继承

Posted _阿锋丶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javascript高级程序设计的几种经典继承相关的知识,希望对你有一定的参考价值。

文章目录

借鉴:https://www.jianshu.com/p/85899e287694

构造方法继承

优点:

  • 可以传参给父类利用call的参数列表传递
  • 避免了所有属性被实例共享

缺点:

  • 没创建一个实例 就要创造一个方法
  • 只能继承父类的实例属性和方法,不能继承原型的属性和方法

function Parent(name)
  this.name = name||'default_name';

  this.getInfo =function()
    return this.name
  


Parent.prototype.say = function()
  console.log('hello');


function Child(name)
  Parent.call(this,name)


var child1 = new Child(['a']);
console.log(child1.name);// ["a"]
// child1.say(); //报错 只能继承父类的实例属性和方法,不能继承原型的属性和方法
// child1.name.push('Bob')
console.log(child1.getInfo()); // ["a"]

var child2 = new Child();
console.log(child2.getInfo());//["default_name"]

原型链继承

特点:所有实例共享属性和方法

function Parent()
  this.name = ['sartre']


Parent.prototype.getName = function()
  return this.name;


function Child()



Child.prototype = new Parent()

var child1 = new Child();
console.log(child1.name); //["sartre"]

child1.name.push('mark') 
console.log(child1.name); // ["sartre", "mark"]

var child2 = new Child();
console.log(child2.name); // ["sartre", "mark"]

组合继承

融合前两者的有点,既可以共享原型方法而且不存在应用属性共享的问题,生成的实例既是子类的实例,优势父类的实例

function Parent(name)
  this.name = name;
  this.hobbies = ['guitar','run','ball'];


Parent.prototype.getName = function()
  console.log(this.name);


function Child(name,age)
  Parent.call(this,name);
  this.age = age || 20;


// 弄懂原型和原型链的关系图 一下就能理解了
Child.prototype = new Parent();
child.prototype.constructor = Child;

var child1 = new Child('sartre','20');

child1.hobbies.push('swim')

console.log(child1.name);
console.log(child1.age);
console.log(child1.hobbies);

var child2 = new Child('mark');

console.log(child1.name);
console.log(child1.age);
console.log(child1.hobbies);

原型式继承

function createObj(o)
  function F()

  

  F.prototype = o;
  return new F();


// 就是 ES5 Object.create 的模拟实现 将传入的对象作为创建的对象的原型

// 缺点:
// 包含引用类型的属性值始终都会共享相应的值,这点跟原型链继承一样

var person = 
  name:'kevin',
  friends:['daisy','kelly']


var person1 = createObj(person);
var person2 = createObj(person)

person1.name = 'person1';
console.log(person2.name); //kevin 这里不是引用类型所以 person2.name 没有改变

person1.friends.push('taylor');

console.log(person2.friends); // ["daisy", "kelly", "taylor"]

寄生式继承

这种方式的继承和构造函数继承的方式一样

function createObj(o)
  var clone = Object.create(o);
  clone.sayName = function()
    console.log('hi');
  
  return clone;

寄生组合式继承

这种继承方法是组合继承的进一步改进
前面的组合继承的缺点就是:会调用两次父构造函数

  • 第一次是设置子类型实例的原型的时候 Child.prototype = new Parent()
  • 第二次是在创建子类型实例的时候
  • var child1 = new Child(‘kevin’,18); 这里执行了new方法 那么就会
    执行 Parent.call(this,name) 调用了 Parent构造函数
function Parent (name) 
  this.name = name;
  this.colors = ['red', 'blue', 'green'];


Parent.prototype.getName = function () 
  console.log(this.name)


function Child (name, age) 
  Parent.call(this, name);
  this.age = age;



// 如果我们不使用 Child.prototype = new Parent() ,
// 而是间接的让 Child.prototype 访问到 Parent.prototype 呢?
var F = function()


F.prototype = Parent.prototype

Child.prototype = new F();



以上是关于javascript高级程序设计的几种经典继承的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript继承的几种实现

javascript中实现继承的几种方式

javascript的几种继承

JavaScript继承的几种方法

JavaScript的几种(原型)继承

javascript实现继承的几种方式