美文网首页
一文搞懂js中的继承

一文搞懂js中的继承

作者: pumpkin1024 | 来源:发表于2021-03-01 08:48 被阅读0次

原型链继承(Prototypal inheritance)

1. [[Prototype]] (对象的属性)

  • [[Prototype]] 是 对象隐藏 属性
  • 它的值要么为 null,要么就是对另一个对象的引用
  • __proto__ 是 [[Prototype]] 的 getter/setter
    Object.getPrototypeOf/Object.setPrototypeOf 来取代 __proto__ 去 get/set 原型
  • 这个属性在对象继承对象时用到

2. prototype (函数的属性)

  • 每个 函数 都有prototype属性
  • 它的值要么是一个对象,要么就是 null
  • 默认的 "prototype" 是一个只有属性 constructor 的对象,属性 constructor 指向函数自身
  • 如果 F.prototype 是一个对象,那么 new 操作符会使用它为新对象设置 [[Prototype]]
  • "prototype" 属性仅在设置了一个构造函数(constructor function),并通过 new 调用时,才具有这种特殊的影响。


function Parent(){
    this.flag = true;
    this.arr = [];
}
function Child(){}
console.log(Child.prototype.constructor);// Child
// 会修改Child.prototype的constructor指向
Child.prototype = new Parent();// 原型链继承
console.log(Child.prototype.constructor);// Parent
const child1 = new Child();
const child2 = new Child();

// 非引用类型不影响
console.log(child1.flag);// true
console.log(child2.flag);// true
child2.flag = false;
console.log(child1.flag);// true
console.log(child2.flag);// false

// 缺点1:引用数据类型共享,修改了child2的arr值,所有实例的值都改变
console.log(child1.arr);// []
console.log(child2.arr);// []
child2.arr.push(1);
console.log(child1.arr);// [1] 
console.log(child2.arr);// [1]
// 缺点2:无法向Parent传参

借用构造函数继承(经典继承)

function Parent(){
   this.flag = true;
   this.arr = [];
}
Parent.prototype.getFlag = function(){}
function Child(){
    Parent.call(this); // 借用构造函数继承
}
// 无法继承Parent prototype的方法 
// 因为prototype只在new时有用
// child1只是Child的实例,而非Parent的实例
const child1 = new Child();
console.log(child1 instanceof Parent);// false

组合继承(原型链+经典)

// 缺点,调用2次父类构造函数
function Parent(){
   this.flag = true;
   this.arr = [];
}
Parent.prototype.getFlag = function(){}
function Child(){
    // 通过经典继承继承实例属性的继承
    Parent.call(this); // 借用构造函数继承
}
// 通过原型链继承prototype方法的继承
Child.prototype = new Parent();// 原型链继承

原型式继承

  1. 接受一个对象A
  2. 返回一个新对象B
  3. 并且B.proto --> A
// 相当于Object.create()
function createObjcet(obj) {
  function F () {};
  F.prototype = obj;
  return new F();
}

寄生式继承

function createObjcet(obj) {
  function F () {};
  F.prototype = obj;
  return new F();
}
function wraop(o){
    var obj = createObjcet(o);
    // 在原型式继承的基础上新增一些函数或属性
    obj.sayName = function(){ 
        console.log(this.name);
    }
    return obj;
}

寄生组合式继承(经典+原型式继承)

  • 和组合继承的区别,用原型式继承代替原型链继承
function createObjcet(obj) {
  function F () {};
  F.prototype = obj;
  return new F();
}
function Parent(){
   this.flag = true;
   this.arr = [];
}
Parent.prototype.getFlag = function(){}
function Child(){
    // 通过经典继承继承实例属性的继承
    Parent.call(this); // 借用构造函数继承
}
// 通过原型式继承prototype方法的继承
Child.prototype = createObjcet(Parent.prototype);
// 修正constructor
Child.prototype.constructor = Child;

参考文章

相关文章

  • 一文搞懂js中的继承

    原型链继承(Prototypal inheritance) 1. [[Prototype]] (对象的属性) [[...

  • 搞懂 JavaScript 继承原理

    摘要: 理解JS继承。 原文:搞懂 JavaScript 继承原理 作者:前端小智 Fundebug经授权转载,版...

  • JS中的原型和原型链详解

    JS中的原型和原型链是大家彻底搞懂JS面向对象及JS中继承相关知识模块非常重要的一个模块,一旦突破这块知识点,相信...

  • JS继承

    JS中的继承 许多OO语言都支持两种继承方式:接口继承和实现继承; 因为JS中没有类和接口的概念 , 所以JS不支...

  • JS中基于原型实现继承

    本文不会对于JS中的继承机制进行深入研究,只聊js中基于原型实现继承的方式,如果需要了解JS中的继承机制及其相关背...

  • JS继承的6种方式及优缺点

    参考文章:一文看懂 JS 继承 构造函数继承 优势 可以定义私有属性方法 子类传递参数给父类 劣势 不能定义共享的...

  • 2019-03-25 继承

    js中通过原型来实现继承 组合继承:原型继承+借用构造函数继承

  • [读] JS中的call()和apply()方法

    JS中的call()和apply()方法 实现继承 多重继承

  • JS中的继承

    1. prototype实现继承 由于IE不支持Man.prototype.proto=Human.prototy...

  • js中的继承

    方式一、原型链继承 分析: 这种方式实现的本质是通过将子类的原型指向了父类的实例,子类的实例就可以通过proto访...

网友评论

      本文标题:一文搞懂js中的继承

      本文链接:https://www.haomeiwen.com/subject/yiamfltx.html