对象的javascript原型 [英] javascript prototype for object

查看:61
本文介绍了对象的javascript原型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

原型如何工作?为什么无法从 e 对象访问xc"?

how the prototype works ? why the "xc" can not be accessed from e object?

请看代码,看评论,我在chorme中测试

please look down to the code , see the comments , i testing it in the 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更合理,但是知识是真实的.非常感谢.

i first think it would useful in css merging ,later i think for working out the dependency, then re-write css is more reasonable, however the knowledge is real. thanks very much.

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];
}

------依赖重写------

------dependency re-write--------

.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
}

推荐答案

这不是 .prototype 属性的用途. 尽管名称如此,.函数的prototype 属性实际上并不是您习惯使用的对象的原型.这是关于 JavaScript 最难理解的事情之一,所以不仅仅是你.

That's not what the .prototype property is for. Despite the name, the .prototype property of functions isn't actually the prototype of the objects you're used to working with. This is one of the hardest things to understand about JavaScript, so it's not just you.

理解 JavaScript 原型系统的关键是new 运算符创建两个对象,而不是一个.我将从四个变量的角度来讨论这个:

The key to understanding the prototype system in JavaScript is that the new operator creates two objects, not one. I'm going to talk about this in terms of four variables:

请注意,这些不是有效的 JavaScript 名称(实际上,它们在大多数编程语言中都不是有效名称).所有这些都发生在幕后,而且大多数实现也不使用这些名称.我这样做是为了明确您通常看不到这些对象.

Note that these aren't valid JavaScript names (in fact, they're not valid names in most programming languages). All of this happens behind the scenes, and most implementations don't use these names either. I'm doing this to make clear that you can't normally see these objects.

当您使用 new 运算符时,JavaScript 大致执行以下步骤.

When you use the new operator, JavaScript does roughly the following steps.

  1. 创建一个对象 [[newPrototype]].
  2. 将 [[newPrototype]].[[myPrototype]] 设置为 [[Constructor]].prototype
  3. 创建一个对象 [[newObject]].
  4. 将 [[newObject]].[[myPrototype]] 设置为 [[newPrototype]]
  5. 将 [[newObject]].[[myPrototype]].constructor 设置为 [[Constructor]]
  6. 调用 [[Constructor]],将 [[newObject]] 作为this".

请注意,[[newObject]].[[myPrototype]] 不是 [[newObject]] 或 [[Constructor]].prototype 的完美匹配.这就是我们在它们之间需要第三个对象的原因:它携带您想要继承的信息(通过 [[newPrototype]].[[myPrototype]]),但它还携带特定于您正在创建的对象的信息(在 [[newObject]].constructor).

Note that [[newObject]].[[myPrototype]] isn't a perfect match for either [[newObject]] or [[Constructor]].prototype. That's why we need a third object between them: it carries the information you want to inherit (through [[newPrototype]].[[myPrototype]]), but it also carries information specific to the object you're creating (in [[newObject]].constructor).

因此我们了解了 .prototype 函数的用途.它不是函数的 [[myPrototype]],也不是您用 new 创建的对象的 [[myPrototype]].它实际上是原型链中的两个级别,而不是一个.

And so we get to what the .prototype function is for. It's not the function's [[myPrototype]], and it's not the [[myPrototype]] for the objects you create with new. It's actually two levels back in the prototype chain, not one.

我希望这个解释能帮助你理解 .prototype 函数的用途.这不是简单的东西,并不是每个解释都适合每个人.这就是为什么我们在这里有这么多解释的部分原因.

I hope this explanation helps you understand what the .prototype function is for. This isn't simple stuff, and not every explanation clicks with everybody. That's part of why we have so many explanations here.

当你第一次创建一个对象时,你可以直接用Object.create()设置它的原型.此功能适用于 IE9 及更高版本(以及所有其他现代浏览器),如果您需要使用旧浏览器,则可以使用 polyfill.要稍后查看该原型,您可以使用 Object.getPrototypeOf(),它也有不错的浏览器支持(尽管 IE 仅在版本 9 及更高版本中支持它).仅使用这两个函数,您可能会像这样创建对象:

When you first create an object, you can set its prototype directly with Object.create(). This function works with IE9 and higher (plus all other modern browsers), and it can be polyfilled if you need to work with older browsers. To see that prototype later, you use Object.getPrototypeOf(), which also has decent browser support (though IE only supports it in version 9 and higher). Using only these two functions, you might create your objects like this:

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 不支持.不过,如果没问题,您可以执行以下操作:

Once an object has been created, there isn't a standard way to reset its prototype yet. ECMAScript 6 defines one (the Object.setPrototypeOf() function), but so far only Chrome and Firefox support it: IE and Safari do not. Still, if that's OK, you could do things like this:

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__ 属性.你可以这样使用它:

There is a non-standard way to reset an existing object's prototype, and it even enjoys good browser support nowadays. To do this, you set the .__proto__ property on any standard object. You could use it like this:

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 等于 {},而不是 undefined?因为Object构造函数有一个.prototype属性,它成为所有通过它创建的Object的默认原型.规范称这个对象为 [[ObjectPrototype]],它是诸如 .hasOwnProperty() 函数之类的地方.

Now, onto your last question: why is Object.prototype equal to {}, rather than undefined? Because the Object constructor function has a .prototype property, which becomes the default prototype of all Objects created through it. The specs call this object [[ObjectPrototype]], and it's where things like the .hasOwnProperty() function live.

这篇关于对象的javascript原型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆