原型如何运作?为什么" xc"无法从e对象访问?
请向下看代码,看评论,我在chorme中测试
var x={a:"xa",b:"xb",c:"xc"};
var e={a:"ea",b:"eb"};
console.log(Object.prototype); // this is {} why? i am expecting it to be null
console.log(e.prototype);
e.prototype=x;
console.log(e.prototype);
console.log(x.c);
console.log(e.c);//this is undefined , why? i am expecting it to be "xc"
console.log(e.a);
console.log(e.b);
console.log(e.prototype.a);
console.log(e.prototype.b);
我首先认为它在css合并中很有用,后来我认为要解决依赖关系,然后重写css更合理,但知识是真实的。非常感谢。
var css={
'classSelectorExpressionIDOnly1':{
css_Ruls_name1:xxxx,
css_Rulss_name2:xxxx
}
'classSelectorExpressionIDOnlyX':{
css_Ruls_name1:xxxx,
css_Rulss_name9:xxxx
}
'classSelectorExpressionIDOnly2':{ '()inherit':["classSelectorExpressionIDOnly1","classSelectorExpressionIDOnlyX"]
css_Ruls_name3:xxxx,
css_Rulss_name5:xxxx
}
}
var mergeResult = Object.create(css.classSelectorExpressionIDOnly2);
for(var entry in mergeResult){
mergeResult[entry]= mergeResult[entry];
}
mergeResult.__proto__=css.classSelectorExpressionIDOnly1;
for(var entry in mergeResult){
mergeResult[entry]= mergeResult[entry];
}
mergeResult.__proto__=css.classSelectorExpressionIDOnlyX;
for(var entry in mergeResult){
mergeResult[entry]= mergeResult[entry];
}
------依赖重写--------
.classSelectorExpressionIDOnly1,.classSelectorExpressionIDOnly2{
css_Ruls_name1:xxxx,
css_Rulss_name2:xxxx
}
.classSelectorExpressionIDOnlyX,.classSelectorExpressionIDOnly2{
css_Ruls_name1:xxxx,
css_Rulss_name9:xxxx
}
.classSelectorExpressionIDOnly2{
css_Ruls_name3:xxxx,
css_Rulss_name5:xxxx
}
答案 0 :(得分:1)
看看这里: https://stackoverflow.com/a/9959753/2768053
阅读完之后,您将把代码转换为:
var x={a:"xa",b:"xb",c:"xc"};
var e={a:"ea",b:"eb"};
console.log(Object.prototype.__proto__);
console.log(e.__proto__);
e.__proto__=x;
console.log(e.__proto__);
console.log(x.c);
console.log(e.c);
console.log(e.a);
console.log(e.b);
console.log(e.__proto__.a);
console.log(e.__proto__.b);
您将得到您期望的结果:)
答案 1 :(得分:1)
这不是.prototype
属性的用途。尽管有名称,但函数的.prototype
属性实际上并不是原型的您习惯使用的对象。 这是关于JavaScript 最难理解的事情之一,所以它不仅仅是你。
在JavaScript中理解原型系统的关键是 new
运算符创建两个对象,而不是一个。我将用四个变量来讨论这个问题:
请注意,这些JavaScript名称不是有效的(实际上,它们在大多数编程语言中都不是有效名称)。所有这些都发生在幕后,大多数实现也没有使用这些名称。我这样做是为了表明你无法正常看到这些物品。
当您使用new
运算符时,JavaScript大致执行以下步骤。
注意[[newObject]]。[[myPrototype]]并不是[[newObject]]或[[Constructor]]。prototype的完美匹配。这就是为什么我们需要它们之间的第三个对象:它携带你想要继承的信息(通过[[newPrototype]]。[[myPrototype]]),但它也包含特定于你所对象的对象的信息。重新创建(在[[newObject]]。constructor)。
所以我们得到.prototype
函数的用途。它不是函数的[[myPrototype]],而且它不是您使用new
创建的对象的[[myPrototype]]。它实际上是原型链中的两个级别,而不是一个级别。
我希望这个解释可以帮助您了解.prototype
函数的用途。这不是简单的事情,并不是每个人都会点击每个解释。这就是为什么我们在这里有这么多解释的部分原因。
首次创建对象时,可以使用Object.create()
直接设置原型。此功能适用于IE9及更高版本(以及所有其他现代浏览器),如果您需要使用旧版浏览器,则可以将其填充。 稍后要查看该原型,您可以使用Object.getPrototypeOf()
,它也具有良好的浏览器支持(尽管IE仅在版本9及更高版本中支持它)。仅使用这两个函数,您可以创建如下对象:
var x = {a:"xa",b:"xb",c:"xc"};
var e = Object.create(x);
x.a = "ea";
x.b = "eb";
console.log(Object.getPrototypeOf(Object));
console.log(Object.getPrototypeOf(e));
console.log(x.c);
console.log(e.c);//this is undefined , why? i am expecting it to be "xc"
console.log(e.a);
console.log(e.b);
console.log(Object.getPrototypeOf(e).a);
console.log(Object.getPrototypeOf(e).b);
创建对象后,还没有一种标准方法可以重置原型 。 ECMAScript 6定义了一个(Object.setPrototypeOf()函数),但到目前为止只有Chrome和Firefox支持它:IE和Safari不支持。不过,如果可以的话,你可以这样做:
var x = {a:"xa",b:"xb",c:"xc"};
var e = {a:"ea",b:"eb"};
console.log(Object.getPrototypeOf(object));
console.log(Object.getPrototypeOf(e));
Object.setPrototypeOf(e, x);
console.log(Object.getPrototypeOf(e));
console.log(x.c);
console.log(e.c);
console.log(e.a);
console.log(e.b);
console.log(Object.getPrototypeOf(e).a);
console.log(Object.getPrototypeOf(e).b);
是重置现有对象原型的非标准方法,现在它甚至享有良好的浏览器支持。为此,您可以在任何标准对象上设置.__proto__
属性。您可以像这样使用它:
var x = {a:"xa",b:"xb",c:"xc"};
var e = {a:"ea",b:"eb"};
console.log(object.__proto__);
console.log(e.__proto__);
e.__proto__ = x;
console.log(e.__proto__);
console.log(x.c);
console.log(e.c);
console.log(e.a);
console.log(e.b);
console.log(e.__proto__.a);
console.log(e.__proto__.b);
现在,关于你的最后一个问题:为什么Object.prototype
等于{},而不是未定义?因为Object
构造函数具有.prototype
属性,该属性成为通过它创建的所有对象的默认原型。规范称这个对象为[[ObjectPrototype]],它就像.hasOwnProperty()
函数之类的东西一样。