JS继承理解

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]//实例属性
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353

推荐阅读更多精彩内容

  • 什么是继承 js中的继承就是获取存在对象已有属性和方法的一种方式. 继承一 属性拷贝 就是将对象的成员复制一份给需...
    LiYajie阅读 5,267评论 1 7
  • 对象继承 什么是继承 继承可以使得子类具有父类的属性和方法或者重新定义、追加属性和方法 实现继承就需要完成两件事 ...
    槑小姐_1419阅读 388评论 0 0
  • 1.原型链继承  原型链继承所带来的问题:   ① 引用类型的属性被所有实例共享。  ② 在创建 Child 的实...
    Knight52033阅读 310评论 0 1
  • 其实要总结这几个概念已经很久了,只是之前一直都觉得自己还不算完全掌握,而且知识点还不够系统,所以一直拖着,但是最近...
    Katherine的小世界阅读 732评论 0 5
  • 前言 此篇文章的目的是让你搞懂这些继承到底是为什么?他们的优缺点的原理到底是什么?看了很多文章说的太抽象,怎么可能...
    沐雨芝录阅读 1,099评论 0 5