![](/img/trans.png)
[英]Undefined 'this' on class extending from EventEmitter when trying to call emit method inside of class
[英]Is it possible to call a class from inside another class (without extending)?
我正在為基本游戲開發不同的組件。
現在我的結構是我有一個種族類的文件,它被導出到另一個文件,在那里我有一個類,它延伸到人類並制造一個玩家。 為玩家提供人類和玩家的屬性。
然而,這意味着如果我想制作一個不是人類的玩家,我將不得不制作一個新的玩家類別,而不是一個不同的種族。 這似乎是糟糕的做法,我想找到一種方法來重構它以使其更好地流動。
這是我的人類課程:
export class Human {
constructor() {
this.type = 'Human';
this.health = 10;
this.baseAttack = 2;
this.baseDefense = 1;
}
這是我的播放器播放器類:
export class Player extends Human {
constructor(name, level){
super();
var inventory = {};
this.name = name;
this.level = level;
this.inventory = inventory;
this.currentCapacity = 0;
this.maxCapacity = 50;
}
Player類中還有與庫存相關的其他功能,但這些功能似乎與我的問題無關。
我的預期結果是我有一組種族,當我制作一個玩家或角色時,我可以從該組中選擇,然后該玩家或角色將繼承該種族的靜態屬性(例如health,baseAttack和baseDefense) 。
正如聰明的孩子所說,更喜歡作文和繼承。 你可以做這樣的事情而不偏離現有的方法:
class Orc {
constructor() {
this.mortal = true
}
}
class Player {
constructor(race, name, level){
var inventory = {};
this.race = race;
this.name = name;
this.level = level;
this.inventory = inventory;
this.currentCapacity = 0;
this.maxCapacity = 50;
}
}
const orc = new Player(new Orc(), 'Baz', 1 )
console.log(orc.race)
還有很多其他方法可以讓這只貓受到傷害,包括讓人類從玩家身上下來。 事實上,這將是使用經典繼承對這些實體進行建模的常用方法(Player是一般情況,人類和獸人更具體)。
class PlayerClassic {
constructor(name, level){
var inventory = {};
this.name = name;
this.level = level;
this.inventory = inventory;
this.currentCapacity = 0;
this.maxCapacity = 50;
}
}
class Human extends PlayerClassic {
constructor(name, level) {
super(name, level)
this.mortal = true
}
}
const human = new Human('Johnny', 2)
console.log(human)
我發現繼承層次結構很少有利可圖。 在上述兩種情況下,你都必須使用typeof來確定你正在處理什么類型的生物。
如果是我的代碼,我可能會完全跳過這些課程。 我可能會做類似以下的事情來構建一個表示構造的玩家的數據結構:
const raceTemplates = {
human: {mortal:true},
elf: { mortal:true}}
const playerMaker = template => (race, name, level)=> {
return {
name,
level,
race,
inventory: {},
currentCapacity:0,
maxCapacity:50,
...template[race]
}
}
const player = playerMaker(raceTemplates)('elf', 'sammy', 2)
console.log(player)
以下是對任何感興趣的人的repl.it鏈接:
要在標題中回答您的問題:
一個類可以包含另一個類嗎?
是的,它可以。
否則,對於您的場景,我將race
視為一種屬性(類似的玩家也可以具有品質,可能需要設置)。 因此,我建議通過工廠方法注入值。 只是提供了一個簡單的亮點,但您可以自己使用更結構化的factory method
。
function raceFactory(raceName) {
if (raceName == 'raceA') {
let res = new Human();
res.health = 30;
return res;
}
}
並在主應用程序中:
let humanRaceA = new factory.RaceFactory('raceA');
這是另一種解決方案
function Player(name, level){
var inventory = {};
this.name = name;
this.level = level;
this.inventory = inventory;
this.currentCapacity = 0;
this.maxCapacity = 50;
}
module.exports.Player = function(race, name, level){
var newPlayer = Object.create(Object.assign(race.prototype, Player.prototype))//override
race.call(newPlayer);
Player.call(newPlayer, name, level);
return newPlayer;
}
在客戶端代碼中,您可以執行以下操作:
var { Player } = require(/* your module */)
var newPlayer = Player(Human, 'Bob', 23);
console.log(newPlayer);
/*
{ type: 'Human',
health: 10,
baseAttack: 2,
baseDefense: 1,
name: 'Bob',
level: 23,
inventory: {},
currentCapacity: 0,
maxCapacity: 50 }
*/
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.