构造函数和原型
有人可以解释这一点吗?构造函数和原型
function Foo() {
this.x = 1;
this.y = 2;
}
function FooProto() {
this.arrow = 1;
this.bow = 1;
}
document.writeln(Foo.prototype); // [object Object]
document.writeln(Foo.prototype.constructor); // function Foo() { x =1; y=2; }
我的理解是:Foo.prototype是一个Object,它的构造函数属性是Function Foo。 。富[[原型]]是Function.prototype的
obj = new Foo;
document.writeln(obj.constructor); // function Foo() { x =1; y=2; }
document.writeln(obj.constructor.prototype); // [object Object]
Foo.prototype = FooProto;
document.writeln(Foo.prototype); // function FooProto() { arrow = 1; bow = 2; }
document.writeln(Foo.prototype.constructor); // function Function() { [native code] }
问题1:你是怎么用[[原型]]发生在这里的抬头。如果有人能向我解释这一点,我将不胜感激。
document.writeln(obj.constructor); // function Foo() { x =1; y=2; } .. no change
document.writeln(obj.constructor.prototype); // function FooProto() { arrow = 1; bow = 2; }
anotherObj = new Foo;
document.writeln(anotherObj.constructor); // function Function() { [native code] }
document.writeln(anotherObj.constructor.prototype); // function Empty() {}
问题2:与问题1相同的问题。Javascript解释器如何执行查找?
在解释基于原型的代码时,使用Object.create
来解释东西要简单得多。 Object.create
是接收原型对象,并创建一个具有原型对象作为其[[原型]]
当一个对象查找的属性是这样工作的一个新的实例对象的函数:
每对象在其内部具有自己的和不可变的[[prototype]]属性。这个属性是秘密和隐藏的,除非你在Firefox中,你可以通过__proto__
得到它。
当读取属性,我们首先在对象本身中搜索它,如果我们没有找到它,我们递归搜索对象的[[prototype]]。
当写一个属性,我们总是写一个自己的属性(我们从不改变[[原型]],即使它也有我们设置的属性。
proto = {a:1};
child1 = Object.create(proto);
child2 = Object.create(proto);
child1.a = 2;
console.log(proto.a); //1
console.log(child1.a); //2
console.log(child2.a); //1
当创建一个功能
每当我们在JavaScript中创建一个函数对象,它带有已经填充到prototype
属性。这是prototype
对象(从Object.prototype中继承),并有constructor
属性设置为相应的功能。
当实例化使用函数构造(新的Foo)
新对象与功能prototype
作为其创建[[原型]和运行该功能对象O到初始化它的对象。
我不真的想解释什么是在第一种情况下怎么回事,因为
Foo.prototype = FooProto;
部分并没有真正意义,并可能不是你想要做的(记住,原型是什么应该是对象,而不是函数)-
至于第二种情况,更改构造函数的
prototype
属性只会影响将来的实例(anotherObj)。已经创建的对象的[[prototype]]属性是秘密和不可变的,所以你不能做任何改变。- 注意,如果你要动态地更改原型和现有的对象(猴子补丁),你可以做到这一点写在现有的原型对象覆盖,而不是用新的替换它的值。
有是在Javascript原型的两个概念。 (我把它作为在语言设计一个名称冲突。)
-
原型在“原型链”。 它是最后一个答案中提到的内部属性。访问它的首选方式是
Object.getPrototypeOf
。var a = {}; Object.getPrototypeOf(a); // Object {} Object.getPrototypeOf(Object.getPrototypeOf(a)); // null, the top of prototype chain. Object.getOwnPropertyNames(Object.getPrototypeOf(a)); // the methods inherited
每构造(我认为实际上可以声明每个函数)具有自己的财产“原型”。它来用于
new
运营商。
的
new
操作者确实2个步骤。
- 首先是创建一个对象,其原型(一日一说,[[原型]])被分配为构造器的原型(第2一个)。
- 其次是运行构造函数(从
prototype.constructor
查找),将创建的对象作为隐含参数this
。
我们您的情况:
第一obj
用其指定为Foo.prototype属性[[原型](原在某些发动机)创建的。
obj.constructor === obj.__proto__.constructor === Foo.prototype.constructor === Foo
obj.constructor.prototype === Function.prototype
请注意构造函数也是一个Function对象。
然后您更改了Foo
的原型。这改变了obj.constructor.prototype
,但不是obj.constructor
,它有不同的参考。 anotherObj
有一个来自以下new
运算符的新[[Prototype]]。
此问题已在这里多年。以下读者也可能会把我困惑。我recommendated新近出版的书自Axel Rauschmayer先生说到博士的JavaScript: