美文网首页
JS继承理解

JS继承理解

作者: EO_eaf6 | 来源:发表于2020-08-24 18:06 被阅读0次

1、原型链继承:

共享父类(实例)属性方法


继承.jpg
function Child(){
    this.subproperty=false
}
function Person(name){
    this.property=true
    this.name=name
    this.child=[1,2,3,4]
}
Child.prototype=new Person("ming")//关键点
var x=new Child()
x.child.push(5)
console.log(x.child)//[1,2,3,4,5]
var y=new Child()
console.log(y.child)//[1,2,3,4,5]

关键代码:
Child.prototype=new Person("ming")//关键点
//执行Person构造函数,Person实例获得property,name,child属性,Child.prototype指向Person实例
Child:{
    prototype:Person{//Person实例也是Child的原型
                [[prototype]]:Person.prototype{//Person原型
                                  constructor:Person
                                           }
                 name:"ming",
                 property:true,
                 child:[1,2,3,4]
                    }
      }

var x=new Child()
x.t="huan"
//new关键字 x. [[prototype]]=Child.prototype,导致继承Person,执行Child构造函数,添加自身属性subproperty
x:{
    [[prototype]]:Person{
                    [[prototype]]:Person.prototype{
                                       constructor:Person
                                            },
                    name:"ming",//共享属性
                    property:true,//共享属性
                    child:[1,2,3,4]//共享属性
                         },
    t:"huan",
    subproperty:false
}

x.child.push(5)
//x实例访问并修改引用属性,原型搜索链:(1)x实例(无child属性)(2)Child.prototype(Person实例有Child属性,更改,实际也是在更改Person实例属性)停止搜索

var y=new Child()
//new关键字 y. [[prototype]]=Child.prototype,导致继承Person,执行Child构造函数,添加自身属性subproperty
y:{
    [[prototype]]:Person{
                    [[prototype]]:Person.prototype{
                                       constructor:Person
                                            },
                    name:"ming",//共享属性
                    property:true,//共享属性
                    child:[1,2,3,4,5]//共享属性
                         },
    subproperty:false
}

原型链继承:
优点:能够共享父类属性和方法,避免每个实例重新定义方法属性占内存
缺点:(1)共享属性如果是引用类型,容易被实例修改
(2)子类在创建实例时,不能动态的向父类构造函数传参,上述父类name值,在第一次使用Child.prototype=new Person("ming")时name值就固定了

2、借用构造函数继承:

(不使用Child.prototype=new Person("ming"),使用call为每个实力作用域复制其私有属性,非共享)

function Person(name){
    this.property=true
    this.name=name
    this.child=[1,2,3,4]
}
function Child(name){
   Person.call(this,name) 
}
var x=new Child()
x.t="huan"
x.child.push(5)
console.log(x.Child)//[1,2,3,4,5]
var y=new Child()
console.log(y.Child)//[1,2,3,4]

Person.call(this,name)
 //创建实例时执行代码,this指向实例对象,因此,这里的this其实是切换到Child实例作用域调用执行Person代码;
//call调用函数是在独立的特定作用域下执行的,每个实例调用后属性值互不干扰
因此,x.child.push(5)其实只作用于x作用域内

优点:能动态传值给父类构造函数,解决原型链的共享引用问题
缺点:相同的方法,不能共享,需要每个实例都声明解析,占内存

3、组合继承:

(原型链+借用构造函数):原型链定义公用方法和属性,借用构造函数定义实例独立方法和属性
个人理解:是因为每个实例在执行Person.call(this,name) 后屏蔽了Person实例中的相同属性,当实例中有了与原型同名的属性后,原型中的属性将会被屏蔽

function Person(name){
    this.property=true
    this.name=name
    this.child=[1,2,3,4]
}
function Child(name){
    Person.call(this,name)  
}
Person.prototype.class=2
Person.prototype.getName=function(){
    return this.name
}
Child.prototype=new Person()
var x=new Child("ming")
x.child.push(5)
console.log(x.child)//[1,2,3,4,5]
console.log(x.getName())//ming
var y=new Child("huan")
console.log(y.child)//[1,2,3,4]
解析:
Child.prototype=new Person()
Child:{
    prototype:Person{//Person实例也是Child的原型
                [[prototype]]:Person.prototype{//Person原型
                                  constructor:Person
                                           },
                 name:undefined,
                 property:true,
                 child:[1,2,3,4]
                    }
      }

var x=new Child("ming")
//执行Child构造函数->执行Person.call()获得实例属性
x:{
    [[prototype]]:Person{
                    [[prototype]]:Person.prototype{
                                       constructor:Person
                                            },
                    name:undefined,//共享属性
                    property:true,//共享属性
                    child:[1,2,3,4]//共享属性
                         },
    name:"ming",//实例属性
    property:true,//实例属性
    child:[1,2,3,4]//实例属性
}

x.child.push(5)
//实例属性child变化,因为通过原型搜索链在实例中搜索到chid属性,搜索停止
x:{
    [[prototype]]:Person{
                    [[prototype]]:Person.prototype{
                                       constructor:Person
                                            },
                    name:undefined,//共享属性
                    property:true,//共享属性
                    child:[1,2,3,4]//共享属性
                         },
    name:"ming",//实例属性
    property:true,//实例属性
    child:[1,2,3,4,5]//实例属性
}

相关文章

  • JS继承理解

    1、原型链继承: 共享父类(实例)属性方法 原型链继承:优点:能够共享父类属性和方法,避免每个实例重新定义方法属性...

  • js继承完全理解

    认识原型链 要理解js的继承原来要先理解原型链,要理解原型链要先清楚下面两个结论: 任何一个构造函数(其实是任何一...

  • js继承再度理解

    https://www.cnblogs.com/xiaohuochai/p/5721552.html 函数有原型,...

  • 搞懂 JavaScript 继承原理

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

  • 原型链概述

    JS原型链用来解决JS中继承关系,目前理解肤浅,实觉强制模仿面向对象,有许多不合理之处。 构造函数的继承: fun...

  • ES5的继承和ES6的继承

    关于js中的继承,已经老生常谈了,本文将对js的继承做一个大概的总结. 首先我们可以看一下,es5继承关系图,理解...

  • 携程面试总结

    1.对js闭包的理解2.对原型的理解3.js怎么实现继承4.js怎么实现私有变量5.angular的双向绑定实现6...

  • JS 中 this 指向及继承

    在理解继承之前,需要知道 js 的三个东西: 什么是 JS 原型链 this 的值到底是什么 JS 的new 到底...

  • 我还没搞懂 JS 中 this 指向及继承,直到有人向我这样解释

    在理解继承之前,需要知道 js 的三个东西: 什么是 JS 原型链 this 的值到底是什么 JS 的new 到底...

  • 我还没搞懂 JS 中 this 指向及继承,直到有人向我这样解释

    在理解继承之前,需要知道 js 的三个东西: 什么是 JS 原型链 this 的值到底是什么 JS 的new 到底...

网友评论

      本文标题:JS继承理解

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