I Shar

I Shar

мир глазами веб-разработчика

JavaScript: Object.setPrototypeOf

как работает метод setPrototypeOf в JavaScript

I Shar

время чтения 2 мин.

Photo by NATHAN MULLET on Unsplash

Согласно определению в JavaScript метод Object.setPrototypeOf() устанавливает прототип указанного объекта в другой объект.

Интересно, какой результат даст следующая задача?

function Human(name, age) {
    this.name = name;
    this.age = age;
}
let user = Object.setPrototypeOf({}, new Human("John", "55"));
console.log(Object.keys(user));
console.log(user.name);

Что мы увидим в консоли в результате исполнения фрагмента кода, приведенного выше?

Попробуем разобраться.

Действительно, метод Object.setPrototypeOf устанавливает новый прототип для объекта. Но сам объект при этом не изменяется, он лишь наследует поведение указанного объекта.

Это утверждение достаточно легко проверить, обратившись к свойству __proto__ до и после изменения прототипа.

Для примера мы создадим объект с единственным свойством name и массив, состоящий из трех элементов:

let user = { name: 'John' },
    arr = [1, 2, 3];
console.log('Original state:');
console.log(user);            // { name: 'John' }
console.log(user[1]);         // undefined
console.log(user.__proto__);  // {}
console.log(user.length);     // undefined
Object.setPrototypeOf(user, arr); // добавляем прототип arr к user
console.log('Modified state:');
console.log(user);            // Array { name: 'John' }
console.log(user[1]);         // 2
console.log(user.__proto__);  // [ 1, 2, 3 ]
console.log(user.length);     // 3

После изменения прототипа объекта user мы получили доступ к полям объекта - донора прототипа. Так, мы смогли получить доступ к длине массива arr и к значениям элементов массива по их индексам.

В нашей задачи произошло то же самое: объект user получил доступ к полям name и age объекта типа Human. При этом сам объект user не получил никаких новых полей.

Метод Object.keys при этом возвращает массив собственных свойств объекта, то есть пустой массив [], так как у объекта user нет собственных перечисляемых свойств.

Таким образом, в консоли мы увидим две строки, первая из которых будет содержать пустой массив, а вторая - строку John, являющуюся значением свойства name.

function Human(name, age) {
    this.name = name;
    this.age = age;
}
let user = Object.setPrototypeOf({}, new Human("John", "55"));
console.log(Object.keys(user)); // []
console.log(user.name); // John


Спасибо за внимание.

    • frontend
    • js

Новые публикации

Далее

Категории

О нас

Frontend & Backend. Статьи, обзоры, заметки, код, уроки.