我在JavaScript中学习原型链并编写了一个演示,但我无法理解结果。
这是我的演示:
function A(){}
const c = new A();
A.prototype.sex = "girl";
A.prototype={
name:"q",
age:12
};
console.log(A.prototype.name);
console.log(c.name);
console.log(c.sex);
这是输出:
"q"
undefined
"girl"
为什么console.log(c.name)
输出undefined
?
答案 0 :(得分:3)
A
是你的构造函数,这意味着当你初始化"时,你需要在新创建的对象上输入你需要的所有东西。它
在你的情况下,你什么都不做。
构造函数有一个prototype属性,该对象是您将由new A()
创建的所有对象将继承自
如果您没有明确地将原型设置为构造函数,那么默认情况下您的原型是一个空对象。
所以在那一行:const c = new A();
c继承一个空对象
当你设置:
A.prototype.sex = "girl";
你正在空对象上创建一个属性,然后你分配给它" girl"
但是这个对象与之前相同(相同的参考)" new"。因此c
仍有参考
但是当你这样做时:
A.prototype={
name:"q",
age:12
};
你改变A的原型,即改变A.prototype的引用,但你不再使用new了。所以没有实际拥有的对象
{
name:"q",
age:12
}
作为原型。 c仍然将前一个对象(记住空的)对象作为原型。
但是如果你这样做:const d = new A()
那么,d.name
将会存在但d.sex
赢了
像你一样改变原型(指定对A.prototype的另一个引用)只会影响A.prototype,而不会影响已经实现的对象'在那次做作之前。
答案 1 :(得分:1)
以下是根据JavaScript spec构建新对象的步骤。
正如您在步骤5和6中所看到的,构造对象的内部原型在构造期间被确定并捕获。
因此,该对象不会维护对“Wither .prototype
值A
在任何给定时间”的原型引用。它维护了“A.prototype
执行new A()
时所具有的价值”的原型参考。这就是为什么你可以通过向它添加新属性来修改c
的内部原型,而不是用新的原型替换A
的原型。
如果您在更换原型后再次执行new A()
,那么当时创建的对象将具有该新原型。
- 让obj成为新创建的本机ECMAScript对象。
- 按照8.12中的规定设置obj的所有内部方法。
- 将obj的[[Class]]内部属性设置为“Object”。
- 将obj的[[Extensible]]内部属性设置为true。
- 让 proto 成为使用参数“prototype”调用F的[[Get]]内部属性的值。
- 如果Type( proto )是Object,请将obj的[[Prototype]]内部属性设置为 proto 。
- 如果Type(proto)不是Object,则将obj的[[Prototype]]内部属性设置为标准内置Object原型对象,如15.2.4中所述。
- 让结果成为调用F的[[Call]]内部属性的结果,提供obj作为此值,并将传递给[[Construct]]的参数列表作为args。
- 如果Type(result)是Object,则返回结果。
- 返回obj。
醇>
答案 2 :(得分:0)
1)你创建一个空类
2)你添加一个静态属性(来自原型)性
3)你为你的班级分配了一个新的原型,但是c保留旧原型
所以'A'是最新的,但'c'仍然得到旧的原型,所以名称不存在,但在更改原型之前设置的性属性存在,所以你找到它。