为什么初始化的 JavaScript 对象不包含原型对象

Why doesn't an initialized JavaScript object contain the prototype object?

本文关键字:对象 原型 包含 JavaScript 初始化 为什么      更新时间:2023-09-26

我尝试使用以下代码向对象添加start方法:

var Bounce = Bounce || {
    Info : {},
    Game : {}
};
Bounce.Game.prototype.start = function() {
    Bounce.log("Starting " + new Bounce.Info());
}

但这会导致以下错误(在Bounce.Game.prototype.start行上):

捕获的类型错误:无法设置未定义的属性"开始"

在Chrome的控制台中查看该对象,我可以看到它不包含prototype对象(但具有toStringvalueOfconstructor等)。

通过在原型访问之前添加以下行来轻松解决此问题:

Bounce.Game = function() {};

我不知道为什么在对象已经初始化时需要这样做?

W3Schools告诉我"每个JavaScript对象都有一个原型",但事实似乎并非如此。

从概念上讲,所有对象都有一个原型,但只有函数对象(包括像 ObjectArray 这样的构造函数,尽管它们不产生函数)具有名为 prototype 的属性。它们是不一样的。

如果你读过 ECMAScript 规范,原型通常表示为 [[Prototype]],这是一个实现细节,位于 JS 引擎中,而不是语言特性。但是,在某些引擎中,[[原型]]是公开的,可以使用__proto__属性(非标准)进行访问。


顺便一提:

  1. 如果你想访问[[原型]]Object.getPrototypeOf()是你的朋友。

  2. 当使用a instanceof b时,它实际上是将a[[原型]]链与bprototype属性进行比较。

  3. 为什么我们说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
    
因此

,受到@Leo评论的启发,我考虑了使用普通{}对象及其原型的解决方案。

我们有这个对象:

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();

看看这个: http://jsbin.com/bapuvo/3/edit