Object.create() 方法执行浅拷贝?
is Object.create() method performs shallow copy?
我是 JavaScript 的新手。当我阅读 Object.create 文档时,它写成 'The Object.create() method creates a new object, using an existing object'(参考: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
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 method is performing shallow copy.
-- 编辑 --
不,它可能看起来是这样,但术语 浅拷贝 是不准确的。这样会更符合原型继承 MDN article here
给定一个对象 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
希望这对您有所帮助。干杯,
与浅拷贝无关。
相反,您已经弄清楚 原型继承 在 Javascript 世界中是如何工作的。
为了更好地理解,让我们将其分为以下两部分:
正在从子对象读取 属性:
当您尝试从子对象访问 属性 时,Javascript 解析器将尝试向上搜索原型链,直到设法找到它,否则 return undefined if not找到了。
在子对象中写入属性
它将首先尝试定位您的目标 属性 所属的对象,然后直接在该对象上设置 属性。
让我们以您的部分代码为例:
bar.details.version = 2.2;
What Javascript parser does:
首先通过原型链搜索找到详情,在foo(即:bar.details === foo.details)
其次,version直接设置在details对象上(所以this.details.version 和 this.details.name 都已 "unexpectedly" 更改,正如您在结果中看到的那样 bar.details.version === foo.details.version === 2.2))
bar.a = 123456;
What Javascript parser does:
在任何事情开始之前,bar 已经定位,不需要搜索原型链,因此,a 将 直接 设置在 bar
(即,这就是为什么只有 bar.a 受到 foo.a 仍然保持原始值的影响:123456)
我是 JavaScript 的新手。当我阅读 Object.create 文档时,它写成 'The Object.create() method creates a new object, using an existing object'(参考: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
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 method is performing shallow copy.
-- 编辑 --
不,它可能看起来是这样,但术语 浅拷贝 是不准确的。这样会更符合原型继承 MDN article here
给定一个对象 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
希望这对您有所帮助。干杯,
与浅拷贝无关。 相反,您已经弄清楚 原型继承 在 Javascript 世界中是如何工作的。
为了更好地理解,让我们将其分为以下两部分:
正在从子对象读取 属性:
当您尝试从子对象访问 属性 时,Javascript 解析器将尝试向上搜索原型链,直到设法找到它,否则 return undefined if not找到了。
在子对象中写入属性
它将首先尝试定位您的目标 属性 所属的对象,然后直接在该对象上设置 属性。
让我们以您的部分代码为例:
bar.details.version = 2.2;
What Javascript parser does:
首先通过原型链搜索找到详情,在foo(即:bar.details === foo.details)
其次,version直接设置在details对象上(所以this.details.version 和 this.details.name 都已 "unexpectedly" 更改,正如您在结果中看到的那样 bar.details.version === foo.details.version === 2.2))
bar.a = 123456;
What Javascript parser does:
在任何事情开始之前,bar 已经定位,不需要搜索原型链,因此,a 将 直接 设置在 bar (即,这就是为什么只有 bar.a 受到 foo.a 仍然保持原始值的影响:123456)