更改[] .__ proto __。constructor和[] .constructor的行为不同

Tho*_*hor 3 javascript arrays constructor prototype

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

请注意,我知道应该避免更改内建属性,因为我想更好地理解基本原理,所以我一直在玩它。

我试图更改的默认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
Run Code Online (Sandbox Code Playgroud)

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

Object.getOwnPropertyDescriptor([].__proto__, 'constructor');
Run Code Online (Sandbox Code Playgroud)

哪个打印

{value: ƒ, writable: true, enumerable: false, configurable: true}
Run Code Online (Sandbox Code Playgroud)

那么[].__proto__.constructor财产是writable

所以我尝试通过设置constructor属性[].__proto__,成功

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

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

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

Pat*_*rts 5

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

[].constructor = ...;
Run Code Online (Sandbox Code Playgroud)

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

[].__proto__.constructor = ...;
Run Code Online (Sandbox Code Playgroud)

覆盖上的构造函数Array.prototype

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

在此处输入图片说明

下面验证该分配实际上创建了自己的属性,array1该属性在上遮盖了继承自的属性Array.prototype