我如何从2个对象继承并将这两个对象用作另一个对象的原型

时间:2014-01-07 23:28:41

标签: javascript prototype

我正在学习js继承和原型设计,我的命名可能完全不对,我很抱歉。

我正在尝试创建一个超级对象和原型2子对象作为属性,然后在其中一个子对象内调用另一个中找到的函数。它出于某种原因不起作用。

更新

我的目标是: 我想做一个小游戏 - 为了好玩和练习。 我的计划是有一个名为(object)的基本对象,它具有定位和其他属性(每个其他对象都有)另一个对象叫做(控件)控件。只有可以移动的对象才会有该对象。

玩家也是对象,他们将拥有“对象”和“控件”。作为他们的原型。

希望稍微澄清一下。

代码:

    // sub Object1
function object(){
    this.speed = 1;
    this.walkDistant = 5;

}

// sub Object2
function controls(){
    this.moveLeft = function(){
        console.log(this.speed , this.walkDistant);
        return this.speed * this.walkDistant;
    }
}

// super Object
function player(){
    // DoesNothing
}

player.prototype.object  = new object();
player.prototype.controls  = new controls();

var firstPlayer = new player();
console.log(firstPlayer.controls.moveLeft());

或者如果你喜欢小提琴:http://jsfiddle.net/rMaKa/1/

3 个答案:

答案 0 :(得分:1)

因为播放器可以控制,您可以将控件与播放器混合使用。你的对象构造函数是一个选择错误的名称,因为构造函数应该以一个资本开始,使它成为Object,你就会覆盖window.Object(坏主意)。出于这个原因,我已将其重命名为Base。播放器基础对象,可以控制,以便从Base继承并将控件混合在中。

有关构造函数的更多信息,请混合ins,实例成员和原型检查this link

function Base() {
  this.speed = 1;
  this.walkDistant = 5;
}

// sub Object2
function Controls() {
}
Controls.prototype.moveLeft = function() {
  console.log(this.speed, this.walkDistant);
  return this.speed * this.walkDistant;
}

// super Object
function Player() {
  //make player have Base instance members
  Base.call(this);
  //make player heve Controls instance members
  Controls.call(this);
}
//player is a base object
Player.prototype = Object.create(Base.prototype);
//repair constrictor
Player.prototype.constructor = Player;
//Player can be controlled, copy controls prototype on player (mixin)
// this would be better suited in a helper function, see link posted in answer
var stuff;
for (stuff in Controls.prototype) {
  if (Controls.prototype.hasOwnProperty(stuff)) {
    Player.prototype[stuff] = Controls.prototype[stuff];
  }
}

var firstPlayer = new Player();

console.log(firstPlayer.moveLeft());

如果您希望播放器拥有控件,您可以尝试以下操作:

function Controls(what) {
  //what do we need to control
  this.controlWhat=what;
}
Controls.prototype.moveLeft = function() {
  console.log(this.controlWhat.speed, this.controlWhat.walkDistant);
  return this.controlWhat.speed * this.controlWhat.walkDistant;
};

function Player() {
  this.speed = 1;
  this.walkDistant = 5;
  this.controls=new Controls(this);
}
var firstPlayer = new Player();

console.log(firstPlayer.controls.moveLeft());

答案 1 :(得分:0)

您可以使用Mixins使用已在其他对象中实现的功能来扩展对象的功能。你也可以知道子对象知道超级对象,如下所示。

function subClassA(containerClass) {
    this.containerClass = containerClass;
    this.methodA = function() {
        console.log(this.containerClass.b.methodB());
    }
}

function subClassB(containerClass) {
    this.containerClass = containerClass;
    this.methodB = function() {
        return 12345;
    }
}

function containerClass() {
    this.a = new subClassA(this);
    this.b = new subClassB(this);
}

var cc = new containerClass();
cc.a.methodA();

Mixin方法看起来像这样:

// extend function to add mixin support
function extend(destination, source) {
    for (var k in source) 
      if (source.hasOwnProperty(k))
        destination[k] = source[k];
    return destination;
}

function subClassA() { }
subClassA.prototype.methodA = function() {
    console.log(this.methodB());
};

function subClassB() { }
subClassB.prototype.methodB = function() {
    return 12345;
};

function superClass() {
    // ----------------
}

// add the subClassA and subClassB functionality
extend(superClass.prototype, subClassA.prototype);
extend(superClass.prototype, subClassB.prototype);

var sc = new superClass();
sc.methodA();

答案 2 :(得分:0)

问题在于您尝试从subObj1访问与subObj2相关的属性,但是superObj继承了这两个属性。

要实现这一点,您应该让subObj1继承subObj2

// sub Object1
function name(){
    this.name = function(){
        var myName = 'FirstName';
        console.log(myName, this.last.lastName);
    }

    this.callName = function(){
        this.name();
    };
}

// sub Object2
function lastName(){
    this.lastName ='someLastName';
}

// super Object
function fullName(){
    // DoesNothing
}

name.prototype.last  = new lastName();
fullName.prototype.name  = new name();

var myName = new fullName();
myName.name.callName();

您可以看到此fiddle