我正在学习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/
答案 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