Метод Object.create() выполняет поверхностное копирование?
Я новичок в JavaScript. Когда я читаю документацию Object.create, она написана так: "Метод Object.create() создает новый объект, используя существующий объект" (ссылка: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create). Ничего не говорится о мелкой копии объекта. Но когда я экспериментировал с приведенным ниже сценарием, я подтвердил, что метод create выполняет поверхностное копирование.
var foo = {
a : 100,
details : {
version : 1.1,
name : 'Demo of object inheritance'
},
printInfo : function(){
console.log(this.details.version);
console.log(this.details.name);
console.log(this.a);
}
}
var bar = Object.create(foo);
foo.printInfo();
bar.printInfo();
console.log("\n Updating the details and property a of bar object");
bar.details.version = 2.2;
bar.details.name = "Bar object changed the name";
bar.a = 123456;
console.log("\n")
foo.printInfo();
bar.printInfo();
Правильно ли мое понимание? Пожалуйста, укажите мне любую документацию, подтверждающую, что метод create () выполняет поверхностное копирование.
Когда я выполнял в Scratchpad, я видел ниже вывод в консоли.
1.1
Demo of object inheritance
100
1.1
Demo of object inheritance
100
Updating the details and property a of bar object Scratchpad/1:21:1
2.2
Bar object changed the name
100
2.2
Bar object changed the name
123456
3 ответа
Это не имеет ничего общего с мелкой копией. Вместо этого вы должны понять, как работает Prototype Inheritance в мире Javascript.
Чтобы лучше понять, давайте разберем это на две части:
Чтение свойства из дочернего объекта:
Когда вы пытаетесь получить доступ к свойству из дочернего объекта, анализатор Javascript будет пытаться выполнить поиск в цепочке прототипов вверх, пока ему не удастся найти его, иначе он вернет undefined, если не найден.
Написать свойство в дочернем объекте
Сначала он попытается определить местонахождение объекта, к которому относится целевое свойство, а затем непосредственно установит это свойство для этого объекта.
Давайте возьмем часть вашего кода в качестве примера:
bar.details.version = 2,2;
What Javascript parser does:
Во-первых, детали будут найдены через поиск по цепочке прототипов и найдены в foo (то есть: bar.details === foo.details)
Во-вторых, версия напрямую устанавливается на объекте details (вот почему this.details.version и this.details.name оба "неожиданно" изменены, как вы видели в результате и в результате bar.details.version === foo.details.version === 2.2))
bar.a = 123456;
What Javascript parser does:
Прежде чем что-либо начинать, bar уже находится, и нет необходимости искать в цепочке прототипов, в результате на панели будет непосредственно установлен a(т. Е. Именно поэтому затрагивается только bar.a с foo.a, все еще удерживающим источник) значение:123456)
Object.Create
вообще ничего не копирует, просто устанавливает переданный объект в качестве прототипа нового объекта:
const person = {name: 'Alex', age: 29}
const newPerson = Object.create(person)
console.log(newPerson)
Для того, чтобы сделать мелкую копию, вы можете использовать Object.assign
,
const newPersonObj = Object.assign({}, person)
console.log(newPersonObj)
метод create выполняет поверхностное копирование.
- РЕДАКТИРОВАТЬ -
Нет, может показаться, что так, но термин " мелкая копия" был бы неточным. Это было бы больше в соответствии со статьей MDN наследования прототипа здесь
Данный объект oA
это имеет name
свойство, функция Object.create(oA)
создает новый объект oB
, Пытаясь получить доступ к собственности oB.name
будет искать цепочку прототипов, пока не найдет один на своем прототипе в oA.name
,
Пример кода ниже:
/* create one object adam */
const adam = {
name: 'Adam',
}
console.log(`does adam have own 'name' property?`, adam.hasOwnProperty('name')) // true
/* create new object bob, whose prototype 'ancestor' is adam */
const bob = Object.create(adam)
console.log(`does bob have own 'name' property? (1)`, bob.hasOwnProperty('name')) // false; the 'name' prop is on adam
/* assigning 'name' on bob doesn't change adam's name, it just 'shadows' it -- accessing 'name' on bob returns the one on bob */
bob.name = 'Bob'
console.log(`does bob have own 'name' property? (2)`, bob.hasOwnProperty('name')) // now true
/* adam and bob now each have their own 'name' property */
console.log(adam.name) // Adam
console.log(bob.name) // Bob
/* show the relationship of adam and bob */
console.log(`is adam a prototype 'ancestor' of bob?`, adam.isPrototypeOf(bob)) // true, linked via Object.create()
console.log(`is bob a prototype 'ancestor' of adam?`, bob.isPrototypeOf(adam)) // false, the prototype points one way
Надеюсь это поможет. Ура,