• 给对象赋值时到底发生了什么?


    前言

    myobject.info = "bat"我们都知道这是在干嘛,没错,是在给对象myobject赋值!!!但你考虑过此时都发生了神马?

    创建对象的方法

    1、文字形式

    var myobject = {}

    2、构造函数 

    var myobject = new Objet()

    揭秘

    myobject.info = "bat",在给对象赋值时,首先会在myobject中查找是否存在属性info,情况可以分为以下三种

    1、myobject中存在info属性,那么“只会”修改myobject中的该属性值,为啥说只会,详情见情况3

    2、myobject中不存在该属性,那么会在[[Prototype]]链上层查找该属性,此时又分为两种情况

    •  [[Prototype]]链上层不存在info属性,那么就会在myobject上创建该属性并赋值bat
    •  [[Prototype]]链上层存在该属性,情况较为复杂等下说

    3、myobject中存在info属性,[[Prototype]]链上层也存在该属性,那么这个info属性就是“屏蔽”属性,也就是说实例属性会屏蔽原型链上的同名属性,我们在使用myobject.info = "bat"时只会更

    改实例上的同名属性的值,而无法更改原型链上的同名属性的值!!!

    向[[Prototype]]链上层已经存在的属性赋值就一定会触发屏蔽吗?

    接下来说一下上面说的较为复杂的情况

    此时的情况是myobject中不存在属性info,[[Prototype]]链上层存在属性info

    1、[[Prototype]]链上层存在属性info,这个属性不是只读的,也就是writable:true,那么会在myobject上直接创建该属性并赋值

    2、[[Prototype]]链上层存在属性info,这个属性是只读的,也就是writable:false,此时运行在严格模式下会抛出error,非严格模式下(标准模式)会静默失败

    3、[[Prototype]]链上层存在属性info,这个属性是setter,也就是访问描述符,那么会调用setter,foo属性并不会被添加到myobejct中,也不会重新定义foo这个setter,因为setter会屏蔽[[PUT]]

    由此可见向[[Prototype]]链上层已经存在的属性赋值不一定会触发屏蔽

    特例

    如果我们希望第二种和第三种情况也发生屏蔽,那么就不要使用“=”,而是使用Object.defineProperty()来向myobject添加属性!!!

    在这里对于原因不做详细的解释了,只要知道“只读属性会阻止[[Prototype]]链下层隐式创建同名属性这个限制”只存在于“=”赋值中,使用Object.defineProperty()则不受影响就好

    其实这样做主要是为了模拟类属性继承,我们将[[Prototype]]链上层的info属性看作父类中属性,它会被myobejct继承,这样一来[[Prototype]]链上层的info属性是只读的那么自然myobejct中的info

    属性也是只读的不可以创建,但是一定要注意实际上并不会发生类似的继承复制

  • 相关阅读:
    select @@identity的用法
    类的实践
    UVA 1572 SelfAssembly(图论模型+拓扑排序)
    UVA 10562 Undraw the Trees(多叉树的dfs)
    sprintf与sscanf用法举例
    UVA 10129 Play on Words(欧拉回路)
    UVA 816 Abbott's Revenge(bfs)
    递增【二分】
    递增【二分】
    递增【二分】
  • 原文地址:https://www.cnblogs.com/kunmomo/p/10492325.html
Copyright © 2020-2023  润新知