метод Object.create () выполняет поверхностное копирование? - PullRequest
0 голосов
/ 23 октября 2018

Я новичок в JavaScript.Когда я читаю документацию Object.create, она написана так: «Метод Object.create () создает новый объект, используя существующий объект» (Ref: 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 () выполняет поверхностное копирование.copy.

Когда я выполнял в 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 ]

0 голосов
/ 23 октября 2018

метод создания выполняет мелкое копирование.

- РЕДАКТИРОВАТЬ -

Нет, может показаться, что так, но термин мелкая копия будет неточным.Это было бы больше в соответствии с прототипным наследованием статья 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

Надеюсь, это поможет.Cheers,

0 голосов
/ 23 октября 2018

Это не имеет ничего общего с мелкой копией.Вместо этого вы должны понять, как Наследование прототипов работает в мире Javascript.

Чтобы лучше понять, давайте разберем это на две части:

Чтение свойства из дочернего объекта:

Когда вы пытаетесь получить доступ к свойству из дочернего объекта, синтаксический анализатор Javascript будет пытаться выполнить поиск в цепочке прототипов вверх, пока не сможет найти его, иначе будет возвращено неопределенное, если не найдено.

Запись свойства в дочернем объекте

Сначала он попытается определить местонахождение объекта, которому принадлежит целевое свойство, а затем непосредственно установить это свойство для этого объекта..

Давайте рассмотрим часть вашего кода в качестве примера:


bar.details.version = 2.2;

 What Javascript parser does:
  1. Во-первых, детали будут обнаружены в результате цепочки прототипов поиска и найдены в foo (то есть: bar.details === foo.details )

  2. Второе, версия непосредственно установлена ​​на детали объект (поэтому 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 )

0 голосов
/ 23 октября 2018

Object.Create вообще ничего не копирует, просто устанавливает переданный объект в качестве прототипа нового объекта:

const person = {name: 'Alex', age: 29}
const newPerson = Object.create(person)

console.log(newPerson)

enter image description here

Чтобы сделать мелкую копию, вы можете использовать Object.assign.

const newPersonObj = Object.assign({}, person)
console.log(newPersonObj)

Это создаст совершенно новую копию.enter image description here

...