【问题标题】:Javascript Prototype ProblemsJavascript 原型问题
【发布时间】:2012-05-06 15:43:17
【问题描述】:

我的情况是我正在使用 Box2DWeb 开发 Canvas 游戏,所以我有一个名为 Sprite 的类,它可以将图像绘制到 Canvas,我现在想创建一个 PhysicsSprite 类从 Sprite 继承方法和属性。

我的 Sprite 类(Sprite.js):

Sprite = function (position, dimension, image) {

  this.Position = position;
  this.Dimension = dimension;
  if (image)
    this.Image = image;
  ...

  this.Draw = function (g) {
    ...
  }
  ...
};

我在 PhysicsSprite (PhysicsSprite.js) 中设置原型,如下所示:

PhysicsSprite = function(position, dimension, world) {

    this.prototype = new Sprite(position, dimension, undefined);
    //alert(this.prototype.Position.X)

    var body = CreateBody();
    this.GetBody = function () { return body; }

    this.Draw = function (g) {
        ...  
    }

    function CreateBody () {
          ...
    }
};

注意 alert(this.prototype.Position.X),它会提醒我位置,但如果我将代码更改为 this.Position.X ,我得到一个错误,同样,如果我有一个 PhysicsSprite 的实例,我必须显式调用原型。

这让我认为我没有设置对象的原型,只是创建了一个名为prototype 的属性,并将其设置为一个新的Sprite

如果有人可以帮助我,并解释我做错了什么,那将不胜感激。 我有阅读障碍,所以我总是拼错变量,这令人沮丧,所以这是我寻找的第一件事,但对我来说一切都很好。

【问题讨论】:

标签: javascript inheritance prototype


【解决方案1】:

这让我认为我没有设置对象的原型,只是创建了一个名为原型的属性,并将其设置为一个新的 Sprite。

没错。此外,您根本没有使用函数的原型,因为您将每个函数直接分配给实例 (this.Draw = function() ...) 而不是原型。


在 JavaScript 中,您有一种称为 构造函数 的东西。使用new 运算符调用的每个函数都是构造函数。

当以这种方式调用函数 (new SomeFunc()) 时,会创建一个新对象(我们称之为 isntance),该对象继承自 SomeFunc.prototype 引用的对象,并且此实例可用通过this 在该函数内部。

现在,继承基本上归结为拥有一个原型 (SomeFunc.prototype),它不是(几乎)空对象(默认),而是从另一个函数的原型继承。

示例:

function A(name) {
    // `this` refers to a new instance
    // lets set some properties:
    this.name = name;
}

// all "class" methods should be assigned to the prototype
A.prototype.getName = function() {
    return this.name;
};


// lets create a child "class"
function B(name, place) {
    // we have to call the parents constructor with the current instance
    // and the arguments we want to pass on.
    // this is like `super(name)` in Java or `A.__init__(self, name)` in Python 
    // (or `super(B, self).__init__(name)` in Python)
    A.call(this, name);
    this.place = place;
}

// here we connect A's prototype with B's prototype in a way that they
// stay independent 
inherits(B, A);

// B's "class" methods
B.prototype.getPlace = function() {
    return this.place;
};

// now we can do
var b = new B('SomeName', 'SomePlace');
alert(b.getName());
alert(b.getPlace());

这就是inherits 的样子(此实现由 Google Closure 库使用):

function inherits(Child, Parent) {
    var Tmp = function() {};
    Tmp.prototype = Parent.prototype;
    Child.prototype = new Tmp();
    Child.prototype.constructor = Child;
}

您会看到Child.prototype 指的是Tmp 的一个实例。但是Tmp的原型和Parent的原型是一样的。也就是说new Tmp()返回的实例继承自Parent的原型,由于这个实例是Child的原型,所以Child的所有实例也会继承自Parent.prototype

使用 ECMAScript 5,这可以简化为

Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;

但本质上是一样的。它创建了一个继承自 Parent.prototype 的新对象。


进一步阅读:

【讨论】:

  • 谢谢,我实现了您的更改,我现在对原型设计有了更多了解
【解决方案2】:

改变

this.prototype = new Sprite(position, dimension, undefined);

Sprite.apply(this, position, dimension, undefined);

您是对的,在更改之前,您将一个对象实例分配给“原型”属性。

原型是构造函数的属性,而不是对象实例——也就是说,您可以通过PhysicsSprite.prototype 访问原型,但不能通过this.prototypex.prototype(其中x = new PhysicsSprite())访问原型。

【讨论】:

  • 你不能给this赋值。
【解决方案3】:

JavaScript 与 Java 截然不同,尽管它们经常被误认为是彼此,因为它们都共享 { 和 }。 :D

一个典型的 JavaScript 类:

function Sprite(a,b) {
    // These are per instance
    this.a = a;
    this.b = b;
}
Sprite.prototype = {
    // These are per class, all instances share them
    Draw: function (g) {
        // ...
    }
};

...而 JavaScript 中的继承非常奇怪。

【讨论】:

  • ... JavaScript 中的继承非常奇怪。 我认为这是 OP 最需要帮助的...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-25
  • 2011-06-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多