众所周知,我们可以使用let obj1 = Object.create(obj)
使obj1的原型指向obj。但是我发现的问题是,为什么两者之间的变化不是双向的?如代码所示。
var obj = { val: 1 };
var obj1 = Object.create(obj);
obj.val = 2;
console.log(obj.val); // 2
console.log(obj1.val); // 2
obj1.val = 3;
console.log(obj.val); // 2
console.log(obj1.val); // 3
为什么要更改obj的属性值,而obj1也会更改。但是我更改了obj1的属性值,但不会更改为obj吗?
为什么会有这样的区别?我听不懂你知道吗?你能告诉我原因吗?谢谢!
答案 0 :(得分:1)
当您尝试访问对象的属性时,javascript首先检查对象是否拥有属性。如果找到它,那就太好了,它将解决该值。如果没有,它将原型链传递到父级并在此处进行检查。它会继续沿着原型链前进,直到找到它或到达链的末端为止,在这种情况下,该值是不确定的。
因此,当您访问obj1.val
时,它将首先检查obj1.val。在第一种情况下,它找不到它,因此它检查obj.val并返回在那里找到的2。在您的第二种情况下,它发现它是自己的3属性,并且不检查obj.val。
相反,当您访问obj.val
时,它将检查obj.val。在这两种情况下,它都找到它,并且它等于2。即使它未能找到自己的属性,它也不会检查obj1,因为obj1不在其原型链中。它将只检查根Object.prototype
(这是定义.toString
之类的对象的基本属性的位置)。
答案 1 :(得分:0)
这个简单的示例说明了创建具有完全相同结果的原型的不同方法。这说明了继承链的工作方式以及“阴影”的结果。
const GrandChild = {};
const Child = {};
const Parent = {};
const GrandParent = {
name: "grandparent"
};
GrandChild.__proto__ = Child;
Child.__proto__ = Parent;
Parent.__proto__ = GrandParent;
GrandChild.__proto__ = Child;
console.log(GrandChild.name, Child.name, Parent.name, GrandParent.name);
Child.name = "Child";
console.log(GrandChild.name, Child.name, Parent.name, GrandParent.name);