评估时的价值
myObject.myMember
我的猜测是,javascript会尝试查找“myMember”条目:
myObject myObject.constructor.prototype myObject.constructor.prototype.constructor.prototype myObject.constructor.prototype.constructor.prototype.constructor.prototype .......
直到成功。
以下代码似乎验证了我的猜测
var MyClass1=function(){
this.key1="value1";
};
var myObject=new MyClass1();
MyClass1.prototype.key2="value2";
console.log(myObject.constructor.prototype.key2=="value2"); //true
console.log(myObject.key2=="value2"); //true :)
但以下代码证明我猜错了
var MyClass1=function(){
this.key1="value1";
};
var MyClass2=function(){
this.key2="value2";
};
var myObject=new MyClass1();
MyClass1.prototype=new MyClass2();
console.log(myObject.constructor.prototype.key2=="value2");//true
console.log(myObject.key2=="value2");// false! why?
javascript通过其原型链查找对象成员的实际算法是什么?
答案 0 :(得分:0)
这是因为在创建myObject实例后,您“重新定义”MyClass1。 这就是它的工作原理:
function BaseClass() {
this.key1 = "value";
};
BaseClass.prototype.method1 = function() { };
function SubClass() {
this.key2 = "value";
}
SubClass.prototype = new BaseClass();
SubClass.prototype.constructor = SubClass; //just to have classnames rendered correctly in webkit
SubClass.prototype.method2 = function() { };
var instance = new SubClass();
console.log(instance instanceof BaseClass); //true
console.log(instance instanceof SubClass); //true
console.log("key1" in instance); //true
console.log(instance.hasOwnProperty(key1));// false
console.log(instance.hasOwnProperty(key2));// true
console.log("key2" in instance); //true;
console.log("method1" in instance); //true;
console.log("method2" in instance); //true;
同样遵循prototypechain最好使用Object.getPrototypeOf(Object.getPrototypeOf(...))
答案 1 :(得分:0)
这是因为您在创建MyClass1.prototype=new MyClass2();
的实例后调用了MyClass1
。
var MyClass1=function(){
this.key1="value1";
};
var MyClass2=function(){
this.key2="value2";
};
MyClass1.prototype=new MyClass2();
var myObject=new MyClass1();
myObject.key1 === "value1";
myObject.key2 === "value2";
让我们检查操作var myObject=new MyClass1()
new
运算符(http://es5.github.com/#x11.2.2)调用[[Construct]]
的{{1}}内部方法(当然是伪代码)。
这是myClass1
(http://es5.github.com/#x13.2.2)次调用(显然是伪代码)中发生的内容的略读版本:
[[Construct]]
通过“实际原型”,我的意思不是你看到的//fun in our operation is MyClass1
function Construct ( fun ) {
//we create a fresh new object
var obi = makeNewObject();
//grab the prototype of MyClass1
var proto = fun.prototype;
//and set the actual prototype of obi to that prototype
setPrototype( obi, proto );
//and then returning the created and altered object, that will be myObject
return obi;
}
- 原型向前看,我们将要创建的实例。对象的fun.prototype
是继承到它的属性,它是它的过去。
可以使用[[Prototype]]
检索,并且在某些实现中可以使用非标准Object.getPrototypeOf
进行设置。
好的,现在我们已经确定了如何使用obj.__proto__
创建对象,为什么你的示例不起作用?
创建new
后替换MyClass1.prototype
会破坏两者之间的链接。 myObject
已经移到了黑暗的一面,它已经完全改变了,一个新的对象现在取代了它,MyClass1
与此无关。
在更改myObject
之前,它包含对象myObject.__proto__ === MyClass1.prototype
的引用。更改对象MyClass1.prototype
后,MyClass1.prototype
将继续引用该旧对象而不是新对象。
答案已经完成了。要重新发布 - myObject.__proto__
功能会在[[Construct]]
和MyClass1.prototype
之间建立链接。当您替换myObject
时,该链接不会更改,因此MyClass1.prototype
会很乐意使用最初链接到的对象。
如果你仍然对如何完成属性提取感到好奇:http://es5.github.com/#x8.12.2我警告你,spec语言读起来很乏味。