dr.Brain

doctor Brain

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

JavaScript: Object.setPrototypeOf

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

dr.Brain

время чтения 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 & Backend. Статьи, обзоры, заметки, код, уроки.