据我所知,在发布有关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;
答案 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
只创建一个对象,并且在Character
和Character
方面没有区别。
如果x
按照原来的方式编写,因为您希望swipe
和Name
真正属于私人(尽管两者都有固定器和吸气器,但我没有看到太多理由为此,您可能希望使用将成为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
个对象是不透明的,默认情况下使用它们创建的属性是不可枚举的。
这是整体模式。 (我在这里尝试坚持使用您的编码风格,为变体道歉。)请注意,这些Villian
和new
要求您使用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
,你可以做同样的事情。唯一改变的是实际的Villian
和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 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();