MST
星途 面试题库

面试题:JavaScript寄生组合继承模式在复杂场景中的应用

假设你正在开发一个JavaScript游戏框架,其中存在多层级的对象继承关系,如`GameObject`作为顶层父类,`Character`继承自`GameObject`,`Player`和`Enemy`又分别继承自`Character`。请阐述如何使用寄生组合继承模式来构建这个继承体系,以确保代码的可维护性、扩展性,并且要考虑如何处理不同层级对象之间复杂的属性和方法的继承与重写,以及可能出现的命名冲突问题。
36.5万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试
  1. 寄生组合继承模式实现继承体系
    • 定义顶层父类GameObject
function GameObject() {
    this.commonProperty = 'I am a game object';
    this.commonMethod = function () {
        console.log('This is a common method of GameObject');
    };
}
  • 定义Character类继承自GameObject
function Character() {
    GameObject.call(this);
    this.characterProperty = 'I am a character';
}
Character.prototype = Object.create(GameObject.prototype);
Character.prototype.constructor = Character;
  • 定义Player类继承自Character
function Player() {
    Character.call(this);
    this.playerProperty = 'I am a player';
}
Player.prototype = Object.create(Character.prototype);
Player.prototype.constructor = Player;
  • 定义Enemy类继承自Character
function Enemy() {
    Character.call(this);
    this.enemyProperty = 'I am an enemy';
}
Enemy.prototype = Object.create(Character.prototype);
Enemy.prototype.constructor = Enemy;
  1. 处理属性和方法的继承与重写
    • 继承:通过寄生组合继承模式,子类会继承父类原型上的方法和属性。例如,PlayerEnemy都继承了Character的属性和方法,而Character又继承了GameObject的属性和方法。
    • 重写:如果子类需要重写父类的方法,直接在子类的原型上定义同名方法即可。例如,如果Player需要重写commonMethod
Player.prototype.commonMethod = function () {
    console.log('This is a overridden common method in Player');
};
  1. 处理命名冲突问题
    • 命名规范:使用前缀或命名空间来避免命名冲突。例如,GameObject相关的属性和方法可以使用gameObject_前缀,Character相关的可以使用character_前缀等。
    • 使用闭包和模块化:将相关的类和功能封装在闭包或模块中,限制变量和函数的作用域。例如,使用ES6模块:
// gameObject.js
export function GameObject() {
    this.gameObject_commonProperty = 'I am a game object';
    this.gameObject_commonMethod = function () {
        console.log('This is a common method of GameObject');
    };
}
// character.js
import {GameObject} from './gameObject.js';
export function Character() {
    GameObject.call(this);
    this.character_property = 'I am a character';
}
Character.prototype = Object.create(GameObject.prototype);
Character.prototype.constructor = Character;
// player.js
import {Character} from './character.js';
export function Player() {
    Character.call(this);
    this.player_property = 'I am a player';
}
Player.prototype = Object.create(Character.prototype);
Player.prototype.constructor = Player;

这样不同模块中的变量和函数不会相互干扰,减少命名冲突的可能性。