对于JS原型链的浅层理解

每个对象,不管是对象直接量、还是构造函数创建的对象,都与另外一个对象关联,这个对象就是我们所说的原型。这里有两个重要的、容易混淆的项:__proto__和prototype。

(1)__proto__:是指向父构造器prototype的引用,称原型属性,就是我们所说的原型。所有实例对象都具有__proto__。

(2)prototype:称原型对象,子类就是从父类的prorotype继承属性,或者实例对象从对应的构造器上继承属性。所有构造器都具有prototype,用于被子构造器或者由他生成的实例对象继承。

设N1、N2、N3是构造器,n3是N3的实例对象,其中N1的父构造器是Object,N1是N2的父亲、N2是N3的父亲,则满足以下:

 n3.__proto__ === N3.prototype 
 N3.prototype.__proto__ === N2.prototype
 N2.prototype.__proto__ === N1.prototype
 N1.prototype.__proto__ === Object.prototype
 Object.prototype.__proto__ === null
复制代码

简单来说,所有对象实例都会通过__proto__去继承父构造器的prototype上的属性,所有构造器若存在父构造器,都会继承父构造器的prototype上属性,以此类推,直至最终Object.prototype。而非prototype上的属性是不会被继承的。以上这种链式继承结构成为原型链。

如何实例化一个对象?

实例对象是通过构造器的constructor构造的,而任意构造器N满足:

 N.prototype.constructor = N
复制代码

因此实例化一个n可以:

 let n = new N()
 或者
 let n = new N.prototype.constructor()
复制代码

由于根据原型链知:n.__proto__ === N.prototype,因此在已知已有实例n的情况下,可以通过以下方式去实例化一个实例n_,效果等同于上述的实例化方法。

 let n_ = new n.__proto__.contructor() 
复制代码

简单描述继承关系

为方便理解,给出以下定义:

(1)从构造器继承而来的属性称继承属性

(2)实例或者构造器在自身prototype内定义的属性,称其自有prototype属性(或prototype属性)

(3)实例或者构造器定义的非prototype属性称自有属性

    let obj = new Object() 
    //  设置Object的自有属性
    Object.some_property = 'some_property'
    Object.some_property === 'some_property' //true
    
    // 设置Object的prototype属性,结果覆盖其自有属性,返回其自有prototype属性
    Object.prototype.some_property = 'some_property_of_prototype'
    Object.some_property === 'some_property_of_prototype' //true
    
    //*1* 实例不能继承构造器自有属性,继承了其自有prototype属性**
    //*2* 实例生成后,即使更改构造器的自有prototype属性内容,只要实例
    //    没有覆盖这个属性,它获取属性值是个原型链追溯的过程,最终值会与
    //    目标构造器prototype属性值保持一致
    obj.some_property === 'some_property_of_prototype'  //true
    
    //*3* 实例覆盖继承属性,生成自有属性some_property 
    obj.some_property = 'some_property_of_self'
    obj.some_property === 'some_property_of_self' //true
    
    //*4* 删除自有属性,属性值仍从构造器property属性继承
    delete obj.some_property
    obj.some_property === 'some_property_of_prototype'  //true
    
    //*5* 删除构造器自有property属性,实例的属性为undefined
    delete Object.Object.some_property
    obj.some_property === undefined   //true
    
复制代码

总结

  1. 每个构造器都可以自定义属性,包括自有属性和自有prototype属性,其中prototype属性是可以被子类或者实例继承。

  2. 查找任一实例o的属性x,会从实例自身的自有属性——>构造器自有属性——>构造器自有prototype属性——>...根据原型链依次查找祖先构造器的自有属性、自有prototype属性...——>Object自有属性、自有prototype属性依次遍历,中间一旦找到匹配项,便立即结束查找,返回结果。

  3. 任意构造器O查找属性x,会从构造器自有属性——>构造器自有prototype属性——>...根据原型链依次查找祖先构造器的自有属性、自有prototype属性...——>Object自有属性、自有prototype属性依次遍历,中间一旦找到匹配项,便立即结束查找,返回结果。

转载于:https://juejin.im/post/5d462952e51d4561ff6667bc

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值