【问题标题】:behaviour of changing [].__proto__.constructor and [].constructor differs改变 [].__proto__.constructor 和 [].constructor 的行为不同
【发布时间】:2019-08-20 00:10:04
【问题描述】:

我目前正在尝试了解 javascript 中的 constructor 属性。

提醒一下,我知道应该避免更改 builtin 的属性,我正在玩弄它,因为我想更好地理解基本原理。

我尝试更改[] 的默认constructor 属性(即数组对象的默认构造函数)

[].__proto__.constructor === [].constructor; // true 

[].constructor = function A(){}; // attempts to reset the constructor property to a new function 

[].constructor; // prints ƒ Array() { [native code] }, which indicate the attempt failed

但是当我检查[].constructor的属性描述符时

Object.getOwnPropertyDescriptor([].__proto__, 'constructor');

打印出来的

{value: ƒ, writable: true, enumerable: false, configurable: true}

所以[].__proto__.constructor 属性是writable

于是我尝试通过[].__proto__设置constructor属性,成功了

[].__proto__.constructor = function B(){};

[].__proto__.constructor; //   prints: ƒ B(){}, which indicate the attempt succeded

为什么通过[] 更改constructor 属性失败但通过[].__proto__ 成功?尽管[].constructor === [].__proto__.constructor 返回了true

【问题讨论】:

    标签: javascript arrays constructor prototype


    【解决方案1】:

    这是由于原型链上的属性阴影。执行时

    [].constructor = ...;
    

    这会在数组上创建一个实例属性,该属性遮蔽类原型构造函数。但是,由于Array.prototype 已经有自己的constructor 属性,因此执行

    [].__proto__.constructor = ...;
    

    覆盖Array.prototype 上的构造函数。

    您可以通过实际存储数组实例并仔细查看其原型链来确认此行为:

    下面验证分配实际上在array1 上创建了一个自己的属性,它隐藏了从Array.prototype 继承的属性。

    function A(){}
    
    var array1 = [];
    
    array1.constructor = A;
    
    console.log(array1.constructor === A);
    console.log(array1.__proto__.constructor === Array);

    【讨论】:

      【解决方案2】:

      .__proto__ 是单变量。当您在其修改的所有实例上修改它时。两个不同数组的__proto__是一样的。

      console.log([].__proto__ === [1,23,3123].__proto__) //true

      但是当您更改数组[] 的实例的constructor 属性时。它不会更改所有实例的所有__proto__

      console.log([] === []) //false

      但是如果你将一个数组存储在变量中,然后改变它的属性,它就会起作用。

      let arr = [];
      arr.constructor = function A(){}
      console.log(arr.constructor)

      【讨论】:

        猜你喜欢
        • 2018-08-05
        • 1970-01-01
        • 1970-01-01
        • 2023-04-06
        • 2016-01-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多