为什么';初始化的JavaScript对象是否包含原型对象?
我尝试使用以下代码向对象添加为什么';初始化的JavaScript对象是否包含原型对象?,javascript,object,prototype,Javascript,Object,Prototype,我尝试使用以下代码向对象添加start方法: var Bounce = Bounce || { Info : {}, Game : {} }; Bounce.Game.prototype.start = function() { Bounce.log("Starting " + new Bounce.Info()); } 但这会导致以下错误(在Bounce.Game.prototype.start行上): 未捕获的TypeError:无法设置未定义的属性“start”
start
方法:
var Bounce = Bounce || {
Info : {},
Game : {}
};
Bounce.Game.prototype.start = function() {
Bounce.log("Starting " + new Bounce.Info());
}
但这会导致以下错误(在Bounce.Game.prototype.start
行上):
未捕获的TypeError:无法设置未定义的属性“start”
查看Chrome控制台中的对象,我可以看到它不包含prototype
对象(但包含toString
、valueOf
和构造函数
等)
通过在原型访问之前添加以下行,可以轻松解决此问题:
Bounce.Game = function() {};
我不知道在对象已经初始化的情况下为什么需要这样做
告诉我“每个JavaScript对象都有一个原型”,但事实并非如此。从概念上讲,所有对象都有一个原型,但只有函数对象(包括构造函数,如
object
,Array
,尽管它们不生成函数)有一个名为prototype
的属性。它们不一样
如果您阅读ECMAScript规范,原型通常表示为[[prototype]],这是JS引擎中的一个实现细节,而不是语言特性。但是,在某些引擎中,[[Prototype]]是公开的,可以使用\uuuu proto\uuuu
属性(非标准)访问
顺便说一下:
Object.getPrototypeOf()
是您的朋友a实例时,它实际上是将a的[[Prototype]]链与b的Prototype
属性进行比较
null
是一切的原型?它也不是指原型
,而是指[[prototype]]:
Object.getPrototypeOf(Object.getPrototypeOf({})) // null
Object.getPrototypeOf(Object.getPrototypeOf(Object.getPrototypeOf([]))) // null
Object.getPrototypeOf(Object.getPrototypeOf(Object.getPrototypeOf(new String("")))) // null
// or shorter like this
({}).__proto__.__proto__ // null
([]).__proto__.__proto__.__proto__ // null
("").__proto__.__proto__.__proto__ // null
{}
对象及其原型
我们的目标是:
var Bounce = Bounce || {
Info : {},
Game : {}
};
我们为给定对象定义prototype
属性
Object.defineProperty(Bounce.Game, 'prototype', {
get: function() {
return Object.getPrototypeOf(Bounce.Game);
}
});
现在,我们可以像往常一样使用原型:
Bounce.Game.prototype.start = function(){
console.log('start');
};
Bounce.Game.start();
检查一下:从概念上讲,所有对象都有一个原型,但只有函数对象有
prototype
属性。它们不一样。如果您阅读ECMAScript规范,原型通常表示为[[prototype]],这是JS引擎中的实现细节,而不是语言特性。但是,在某些引擎中,[[Prototype]]可以通过\uuuu proto\uuu
property.No访问。每个物体都有一个原型。但是,它没有名为prototype
的属性。两件不同的事情。是的,这令人困惑。但是,函数的prototype
属性成为使用该函数作为构造函数创建的新对象的实际原型,这一事实与它们相关。应该注意的是\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu>是非标准的-有更好的。@Leo是对的,但是您将无法调用Bounce.Game.start()。看看这个:的确是个有趣的问题,很高兴它被重新打开。这让我想到了一个解决办法。。。我会写一个有趣的答案。但是为什么不干脆Bounce.Game.start=function…
?出于继承和内存节省的原因,原型应该在不同的实例之间“共享”。这个解决方案是针对@Mikaveli提出的问题,也许我永远不会使用这种方法。例如,我们不知道这段代码在哪里使用以及如何使用:如果它在完全符合CommonJS的环境中,我宁愿使用适当的模块设计解决方案(想想nodejs或Tianium)。@Leo回答你的问题:是的,它是一样的。由于您不打算对普通对象使用new
操作符,所以使用prototype变得毫无意义。