在这种情况下在JavaScript中实现继承[更具体地说是node.js]

时间:2013-10-10 05:51:57

标签: javascript node.js inheritance game-engine

  

据我所知,在发布有关a的问题时会被忽视   编程语言然而我似乎无法绕过这个   一个,这真让我沮丧。

我正在编写一个节点js的游戏,我想继承这个类...我不知道怎么样,语法会让我失望,这个东西的教程似乎做了千万种不同的方法我的方法,使用构造函数和所有。

基本上我的问题是如何子类下面的代码。

/* Character class*/
var character = function(startX) {
    var x = startX,
        swipe = 0;

    var getX = function() {
        return x;
    };

    var getSwipe = function(){
        return swipe;
    };

    var setX = function(newX) {
        x = newX;
    };

    var setSwipe = function(newSwipe){
        swipe = newSwipe;
    };

    return {
        getX: getX,
        getSwipe: getSwipe,
        setX: setX,
        setSwipe: setSwipe
    };

}

exports.Character= Character;

2 个答案:

答案 0 :(得分:3)

使用以该形式编写的代码(您没有使用new并且您拥有真正的私有数据),主要的障碍是Character没有任何可以共享的内容实例之间。因此,虽然您可以使用Character生成的对象作为其他对象的原型,但您不能拥有一个 Character对象,并将其重用为多个派生对象的原型。

以下是如何编写一个函数(Villian,比如说)生成的对象,每个对象都将自己的底层Character对象作为原型:

function Villian(startX) {
    var rv = Object.create(Character(startX));

    rv.doEvilThing = function() {
    };

    return rv;
}

Villian创建一个新的Character对象,并将其指定为对象Villian创建的原型。当然,这意味着每次调用Villian都会创建两个对象,而不是只有一个,如果Character部分Villian我们可以在Villian之间重复使用。

您可以Character直接从function Villian(startX) { var rv = Character(startX); rv.doEvilThing = function() { }; return rv; } 扩展对象:

Villian

只创建一个对象,并且在CharacterCharacter方面没有区别。


如果x按照原来的方式编写,因为您希望swipeName真正属于私人(尽管两者都有固定器和吸气器,但我没有看到太多理由为此,您可能希望使用将成为ES6 private properties基础的模式,这与您当前使用的模式不同,对共享原型对象很友好。

我已经written an article了解如何在不等待新的ES6功能的情况下完成这项工作。简而言之:ES6将引入新的“var x = new Name(); // Create the private name object this[x] = value; // Put a property on the object with that name ”对象,这些对象不是字符串,但可以用作属性的名称。引用属性时,可以使用该对象代替名称。 E.g:

Name

私有Character个对象是不透明的,默认情况下使用它们创建的属性是不可枚举的。

这是整体模式。 (我在这里尝试坚持使用您的编码风格,为变体道歉。)请注意,这些Villiannew要求您使用Character,与new不同以上。下面我将展示如何在没有var Character = (function() { var x = new Name(); // The *name* for our `x` property var swipe = new Name(); // The *name* for our `swipe` property /* Character class*/ var Character = function(startX) { this[x] = startX; this[swipe] = 0; }; Character.prototype.getX = function() { return this[x]; }; Character.prototype.getSwipe = function(){ return this[swipe]; }; // ...etc... return Character; })(); var Villian = (function() { /* Villian class*/ var Villian = function(startX) { Character.call(this, startX); }; Villian.prototype = Object.create(Character.prototype); Villian.prototype.doEvilThing = function() { // ... }; return Villian; })(); 的情况下执行此操作(这是一个小小的更改)。

Name

请注意,我们现在在原型上有各种各样的方法,属性确实是属性(而对于你使用的模式,它们是私有的,而不是属性),但是因为我们的作用域函数之外没有代码可以访问对于它们的Name个对象,没有外部代码可以使用这些属性。

在ES5及更早版本(例如今天),您需要一个代替ES6 var Name = function() { var used = {}; function Name() { var length, str; do { length = 5 + Math.floor(Math.random() * 10); str = "_"; while (length--) { str += String.fromCharCode(32 + Math.floor(95 * Math.random())); } } while (used[str]); used[str] = true; return new String(str); // Since this is called via `new`, we have to return an object to override the default } return Name; }(); 的功能。我在文章中给出的那个只使用非重复的随机字符串:

new

如果没有Character,你可以做同样的事情。唯一改变的是实际的Villianvar Character = (function() { var x = new Name(); // The *name* for our `x` property var swipe = new Name(); // The *name* for our `swipe` property /* Character class without using `new` */ var Character = function(startX) { var c = Object.create(Character.prototype); c[x] = startX; c[swipe] = 0; return c; }; Character.prototype.getX = function() { return this[x]; }; Character.prototype.getSwipe = function(){ return this[swipe]; }; // ...etc... return Character; })(); var Villian = (function() { /* Villian class without using `new` */ var Villian = function(startX) { var v = Object.create(Villian.prototype); Character.call(v, startX); return v; }; Villian.prototype = Object.create(Character.prototype); Villian.prototype.doEvilThing = function() { // ... }; return Villian; })(); 函数,但为了清晰起见,我将包含整个内容:

{{1}}

答案 1 :(得分:1)

如果你想要一种更传统的继承方法,为什么不修改你的角色函数来利用函数原型?

var Character = function(startX) {
    this.x = startX;
    this.swipe = 0;
}

Character.prototype.getX = function() {
    return this.x;
};

Character.prototype.getSwipe = function(){
    return this.swipe;
};

Character.prototype.setX = function(newX) {
    this.x = newX;
};

Character.prototype.setSwipe = function(newSwipe){
    this.swipe = newSwipe;
};


function Villian(startX, villianStuff){
    //pull in the base Character's stuff
    Character.call(this, startX);

    //set up the sub "class"'s stuff
    this.villianStuff = villianStuff;
}

//inherit all of those public Character functions 
Villian.prototype = Object.create(Character.prototype);

//now add whatever new Villian stuff you need
Villian.prototype.whatever = function() { };

var c1 = new Character(),
    c2 = new Character(),
    v1 = new Villian();