英文:
Confusion about Object.create() vs Object Literals
问题
I am currently completing the front-end web development course offered by Meta.
I am confused with the usage of Object.create() and Object Literals. Let's use the following code for reference:
let bird = {
hasWings: true,
canFly: true,
hasFeathers: true
};
let eagle = bird;
console.log("Eagle can fly: ", eagle.canFly); //"Eagle can fly: " true
eagle.canFly = false;
console.log("Eagle can fly: ", eagle.canFly); // "Eagle can fly: " false
let penguin = Object.create(bird);
penguin.canFly = false;
console.log("Penguin can fly: ", penguin.canFly); //"Penguin can fly: " false
If I can achieve the same results by simply using the object literals like in the case of eagle, then what difference does using
Object.create()` make in the case of penguin?
I tried to take help from ChatGPT, but it was confusing.
英文:
I am currently completing the front-end web development course offered by Meta.
I am confused with the usage of Object.create() and Object Literals. Let's use the following code for the reference:
let bird = {
hasWings: true,
canFly: true,
hasFeathers: true
};
let eagle = bird;
console.log("Eagle can fly: ", eagle.canFly); //"Eagle can fly: " true
eagle.canFly = false;
console.log("Eagle can fly: ", eagle.canFly); // "Eagle can fly: " false
let penguin = Object.create(bird);
penguin.canFly = false;
console.log("Penguin can fly: ", penguin.canFly); //"Penguin can fly: " false
If I can achieve the same results by simply using the object literals like in case of eagle, then what difference does using
Object.create()` make in the case of penguin?
I tried to take help from ChatGPT, but it was confusing.
答案1
得分: 0
使用您的代码,我可以重写类似于以下的内容:
let bird = {
hasWings: true,
canFly: true,
hasFeathers: true
};
let eagle = bird;
console.log("Eagle can fly: ", eagle.canFly); // "Eagle can fly: " true
eagle.canFly = false;
console.log("Eagle can fly: ", eagle.canFly); // "Eagle can fly: " false
// 但是您也改变了BIRD!!!
console.log("Bird can fly: ", bird.canFly); // Bird cannot fly :(
bird.canFly = true;
console.log("Bird can fly: ", bird.canFly); // Bird can fly again :)
// 但是您又改变了EAGLE!
console.log("Eagle can fly: ", eagle.canFly); // Eagle can fly again, even if you set false before
为了避免这些问题,Object.create()
将为您提供一个新的对象,不包含来自其他对象的引用。
let eagle = Object.create(bird);
类似这样。
英文:
Using your code, I could rewrite something like this:
let bird = {
hasWings: true,
canFly: true,
hasFeathers: true
};
let eagle = bird;
console.log("Eagle can fly: ", eagle.canFly); //"Eagle can fly: " true
eagle.canFly = false;
console.log("Eagle can fly: ", eagle.canFly); // "Eagle can fly: " false
// but you changed BIRD also!!!
console.log("Bird can fly: ", bird.canFly); // Bird cannot fly :(
bird.canFly = true;
console.log("Bird can fly: ", bird.canFly); // Bird can fly again :)
// but you changed EAGLE again!
console.log("Eagle can fly: ", eagle.canFly); // Eagle can fly again, even if you set false before
To avoid those problems, Object.create()
will give you a new object without any references from other objects.
let eagle = Object.create(bird);
Something like that.
答案2
得分: 0
我相信这里有很多细节需要解释,所以让我们逐一开始。
根据定义,Object.create 创建另一个对象并将其原型设置为您作为第一个参数传递的对象。
基本上在您的情况下,当您创建penguin对象时,您检索到一个空对象并将其原型设置为bird对象。
尝试记录penguin对象并查看其属性,您会感到非常惊讶。
这是JavaScript用来管理继承的一种称为原型链的机制。
正如您所看到的,Object.create方法并不像看起来那么直接,我鼓励您阅读以下链接以了解更多信息。
对象字面量和Object.create方法之间的区别在于它们用于在非常基本的层面实现不同的结果。
另外,请记住,当您直接将bird对象分配给eagle时,您并未存储其值,而是存储了它的实际引用。
bird和eagle变量都指向内存中的同一对象,这就是为什么更改一个对象中的属性将反映在另一个对象中的原因。现在,如果您希望在eagle变量中存储bird对象的新副本,我建议使用以下方法:
let bird = {
hasWings: true,
canFly: true,
hasFeathers: true
};
let eagle = { ...bird };
这样做将让您拥有两个独立的对象,修改一个对象中的值将不会影响另一个对象。
英文:
I believe there are a lot of details that we need to explain here, so let us start one by one.
The Object.create by definition creates an another object and sets its prototype to the object that you have passed as the first argument.
Essentially in your case when you created the penguin object, you retrieved an empty object and set its prototype to the bird object.
Try logging the penguin object and take a look at its properties, you will be much surprised.
This is a mechanism that Javascript uses in order to manage inheritance called prototype chaining.
As you can see the Object.create method is not as straight forward as it seems and I would encourage you to read more about it on the following links.
The difference between using Object Literals and the Object.create method is that they are used to achieve different results in a very fundamental level.
Additionally, keep in mind that when you are assigning the bird object directly to the eagle, you are not storing its value, but its actual reference.
Both the bird, and the eagle variables are pointing out to the same object in memory and that is why changing a property in one of the objects will be reflected in the other one. Now essentially if you want to store a fresh copy of the bird object in the eagle variable I would suggest using the following method:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
let bird = {
hasWings: true,
canFly: true,
hasFeathers: true
};
let eagle = {...bird};
<!-- end snippet -->
Doing this, will let you have two independent objects and modifying the values in one object will not affect the other.
答案3
得分: 0
好的,以下是翻译好的部分:
- 要充分理解
Object.create
,你必须了解原型继承。 - 当你执行类似
let eagle = bird
的操作时,你并没有创建一个新的对象eagle。你只是创建了一个新的引用eagle,它指向了bird对象。
从你的代码中,我看到你尝试做以下操作:
- 创建一个通用的鸟对象。
- 创建一个鹰对象,它是一种鸟。
- 创建一个企鹅对象,它也是一种鸟。
你希望鹰和企鹅可以'继承'鸟的属性。
-
使用对象字面量创建一个通用的鸟对象:
let bird = { hasWings: true, canFly: true, hasFeathers: true };
-
创建一个鹰对象:
let eagle = Object.create(bird);
通过使用object.create
,你正在设置eagle的原型为bird。在控制台中尝试以下代码:
Object.getPrototypeOf(eagle) === bird
它会评估为true。
现在,当你调用eagle.canFly
时,JavaScript运行时会检查eagle对象是否有canFly
属性。它没有。因此,它将沿着原型链向上查找并检查bird。bird确实有canFly
属性,而且它的值为true。因此,eagle.canFly
将评估为true。
老实说,这里有很多需要修复的地方。我实际上写了一系列关于原型继承的文章。我建议你阅读它们:
英文:
Okay, there is a lot missing here.
- To fully appreciate Object.create, you must understand prototypal inheritance
- When you do something like
let eagle = bird
, you are not creating a new object, eagle. You are just creating a new reference, eagle, that is pointing to the bird object
From your code, I see that you are trying to do the following:
- Create a generic bird
- Create an eagle, which is a type of bird
- Create a penguin, which is a type of bird
You want eagles and penguins to 'inherit' the properties of birds.
-
Create a generic bird using an object literal
let bird = { hasWings: true, canFly: true, hasFeathers: true };
-
Create an eagle
let eagle = Object.create(bird)
By using object.create, you are setting the prototype of eagle to be bird.
Try this in the console:
Object.getPrototypeOf(eagle) === bird
It will evaluate to true.
Now, when you call eagle.canFly, the JavaScript runtime will check if the eagle object has a canFly property. It does not. So it'll move up the prototype chain and check bird. bird does have the canFly property, and its set to true. Hence eagle.canFly will evaluate to true.
Honestly, there's a lot to fix here. I actually wrote a series on prototypal inheritance. I recommend going though it:
Part 1 - Understanding the Prototype Chain
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论