2

我正在将我在 Flash/AS3.0 中设计的游戏重写为 javascript,并且在学习了类之后无法将我的头脑围绕在原型上。我已经阅读了大量有关它的信息,但仍然不太确定如何将其应用于这种情况。

所以...在我的 AS3.0 项目中,我有一个关卡类,它包含游戏所有关卡中发生的内容、Enter_Frame 功能等。然后我在每个关卡中扩展了该类,以获得关卡特定的详细信息,例如物品放置,地形细节等......所以我的问题是如何做到这一点最有效和“正确”的方式。

现在我有两个功能:

function level() {
//generic level functionality
}

function level1() {
//level1 specific functionality
}

然后,正如我所读的那样,我应该设置

level1.prototype = new level();

但是我发现这会在运行时执行级别函数中的所有内容,这是我不想要的。理想情况下,我想要一个开始按钮来实例化 level1,并且 level1 具有 level 的属性和方法 - 并且,如果可能的话,在发生这种情况时执行 level1 和 level 的构造函数中的所有内容......这可能吗?

我确定这很明显,但我似乎无法点击,抱歉,如果我问的是一个愚蠢的问题。非常感谢提前提供的任何帮助。

4

4 回答 4

2

为了避免在建立继承时执行构造函数,您可以使用Object.create()

level1.prototype = Object.create(level.prototype);

但是,要“链接”构造函数调用,您还需要在:call levellevel1

function level1() {
    level.call(this);

    // ...
}

Usingcall允许您传递上下文 ( this),以便两个构造函数使用同一个对象。

于 2013-07-11T08:41:34.507 回答
0

您想要实现的是 JavaScript 中的某种面向对象的解决方案。看看这篇博文,它详细描述了它,并给出了一个很好的例子。:-)

于 2013-07-11T08:37:07.980 回答
0

用户 JonathanLonowski 已经回答了您关于在设置继承时如何避免调用构造的问题。但我也读到你的问题是关于继承如何在 JavaScript 中工作的一般问题。所以这是我试图解释这个话题的尝试:

说到继承,你基本上想做的就是增强原型链。

那么,它的原型链是什么?

当您使用 ie 请求对象的属性时obj.prop,JavaScript 首先检查该对象obj是否具有这样的属性。如果没有,它会检查该对象的原型是否具有这样的属性。如果没有,它检查原型的原型是否有这样的属性等等。

当您通过编写使用构造函数创建新对象时,obj = new B()原型链如下所示:

obj -> B.prototype -> Object -> null

继承如何与原型链一起工作

如果您希望您的B对象从 type 的对象继承A,您希望您的原型链看起来像这样:

obj -> B.prototype -> A.prototype -> Object -> null

为了实现这一点,你在之后“打破”原型链B.prototype并插入完整的原型链A。或者换句话说,您想设置B.prototype为指向A.prototype

您可以像以前一样执行此操作:

B.prototype = new A();

现在为什么这行得通?所创建的对象new A()具有以下原型链:

objA -> B.prototype -> Object -> null

如果您B.prototype使用此对象覆盖,则类型对象的原型链B如下所示:

objB -> objA -> A.prototype -> Object -> null

如您所见,它有效。通过简单地覆盖B.prototype,您只会丢失一些属性,例如constructor属性。因此,如果您尝试获取withconstructor类型的对象,它首先查找对象本身并没有找到它,然后查找并没有找到它,然后查找并找到它,这是错误的。尽管您并不经常需要该属性,但在覆盖后再次设置它可以被认为是一种好习惯:BobjB.constructorobjAA.prototypeAconstructorB.prototype

B.prototype = new A();
B.prototype.constructor = B;

现在,您的方式只是实现原型链链接的一种方式。JonathanLonowski 的解决方案是另一种解决方案,而且确实是更好的解决方案,因为它不调用 function A。它创建一个空对象,其原型链与 type 对象相同A

(empty object) -> A.prototype -> Object -> null

另一种解决方案是不覆盖B.prototype而是将其修改为简单地指向A.prototype而不是Object. 并非每个浏览器都支持这一点,但在某些浏览器中,您可以通过设置__proto__属性来实现这一点:

B.prototype.__proto__ = A.prototype;

这将产生以下原型链:

obj -> B.prototype -> A.prototype -> Object -> null

请注意,我在这里和那里简化了它,但我认为这应该让您了解它是如何工作的。要理解的最基本的事情是原型设计。现在,从技术上讲,只有一个真正的原型属性,每个对象都有,那就是内部[[prototype]]属性。您不能直接在 JavaScript 中访问它,但您必须在某些条件下设置.prototype.__proto__操作它。

于 2013-07-11T09:53:35.670 回答
0

可以使用 调用父构造函数Obj.call(this,args)。代码还应该保留level1原型的分配,level1.prototype = new level()因为这将在两个对象之间创建类似继承的关系。

function level(config) {
    if(config){
       this.someProperty = config.prop;
       alert("Level constructor");
       alert("Level property " + this.someProperty);
    }
}

function level1(config) {
   level.call(this, config);
   this.someProperty2 = config.prop2;
   alert("Level1 Construtor");
   alert("Leve1 property " + this.someProperty2);
   alert("Level1 using prop from level " + this.someProperty);
}

level1.prototype = new level();

var myLevel = new level1({
    prop: "Test prop",
    prop2: "Test prop2"
});

工作示例 http://jsfiddle.net/kz2Xc/1/

于 2013-07-11T08:39:23.993 回答