поведение изменения [] .__ proto __. конструктор и [] .constructor отличается - PullRequest
3 голосов
/ 29 марта 2019

В настоящее время я пытаюсь понять свойство constructor в javascript.

Просто на голову, я понимаю, что изменения свойств встроенных элементов следует избегать, я играю с этим, потому что хочу лучше понять основные принципы.

Я пытался изменитьсвойство 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?

Поэтому я пытаюсь установить свойство constructor с помощью [].__proto__, оно успешно

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

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

Почему не удалось изменить свойство constructor с помощью [], а с помощью [].__proto__ успешно?Даже если [].constructor === [].__proto__.constructor вернул true.

Ответы [ 2 ]

5 голосов
/ 29 марта 2019

Это связано с затенением свойств в цепочке прототипов.Когда вы выполняете

[].constructor = ...;

, это создает свойство экземпляра в массиве, которое shadows конструктор прототипа класса.Однако, поскольку Array.prototype уже имеет собственное свойство constructor, выполнение

[].__proto__.constructor = ...;

перезаписывает конструктор на Array.prototype.

Вы можете подтвердить это поведение, фактически сохранив экземпляр массиваи приглядимся к цепочке прототипов:

enter image description here

Ниже подтверждается, что присвоение фактически создает собственное свойство в array1, которое скрывает унаследованное свойство от Array.prototype.

function A(){}

var array1 = [];

array1.constructor = A;

console.log(array1.constructor === A);
console.log(array1.__proto__.constructor === Array);
1 голос
/ 29 марта 2019

.__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)
...