2016-03-21 193 views
0

试图用头戴围绕javascript组合使用assign。我的基础对象上的属性意外地在实例之间共享。我究竟做错了什么?我有...Javascript Object Object with assign&Object.create

Stat.js:

import assign from 'object-assign'; 
var Stat = assign({}, { 
    _value: undefined, 

    get: function() { 
     return this._value; 
    }, 

    set: function(n) { 
     var max = this.getMax(); 

     if(n > max) { 
      this._value = max; 
     } else { 
      this._value = n; 
     } 
    }, 

    getMax: function() { 
     return 1; 
    } 
}); 
module.exports = Stat; 

HitPoints.js:

import assign from 'object-assign' 
import Stat from './Stat.js'; 

var HitPoints = assign({}, Stat, {   
    getMax: function() { 
     return 100; 
    } 
}); 
module.exports = HitPoints; 

Unit.js:

import assign from 'object-assign'; 
import HitPoints from 'HitPoints.js'; 

var Unit = assign({}, { 
     hp: Object.create(HitPoints) 
    } 
); 
module.exports = Unit; 

用法:

import Unit from 'Unit.js'; 

var u1 = Object.create(Unit); 
console.log(u1.hp.get()); // undefined - ok 
u1.hp.set(11); 
console.log(u1.hp.get()); // 11 - ok 

var u2 = Object.create(Unit); 
console.log(u2.hp.get()); // 11 - ??? 
u2.hp.set(22); 
console.log(u1.hp.get()); // 22 - ??? 
console.log(u2.hp.get()); // 22 

感谢您的帮助......

+0

这里使用'assign'没有任何好处。 'hp'是共享的,因为'u1'和'u2'都有'Unit'(单个对象)作为原型。 'Object.create(Unit)'不会创建'Unit'的*副本,如果这就是你的想法。 –

+0

@Felix Kling我明白了...所以,我该如何做到这一点。我是来自AS3的javascript n00b。以上内容受到JavaScript对象[这个解释](http://www.datchley.name/delegate-object-to-classical-inheritance/)的启发。 –

+0

我建议使用构造函数:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript#Custom_objects。 –

回答

-1

嗯,这个工作...

Stat.js:

var Stat = { 
    get: function() { 
     return this._value; 
    }, 

    set: function(n) { 
     var max = this.getMax(); 

     if(n > max) { 
      this._value = max; 
     } else { 
      this._value = n; 
     } 
    }, 

    getMax: function() { 
     return 1; 
    } 
} 

HitPoints.js:

var HitPoints = function() { 
    return assign(Object.create(Stat), {  
     getMax: function() { 
      return 100; 
     } 
    }); 
} 

Unit.js:

var Unit = function() { 
    return assign({}, 
     Object.create(XYPiece), 
     Object.create(TeamMember), 
     { 
      hp: HitPoints()  
     } 
    );      
} 

用法:

var u1 = Unit(); 
console.log(u1.hp.get()); // undefined 
u1.hp.set(11); 
console.log(u1.hp.get()); // 11 

var u2 = Unit(); 
console.log(u2.hp.get()); // undefined 
u2.hp.set(22); 
console.log(u1.hp.get()); // 11 
console.log(u2.hp.get()); // 22 

This文章帮助。万岁!

不过,寿,如果这是从根本上去做一个愚蠢的方式,告诉我...

5

对于初学者来说,使用class的,为什么人们不想要一个简单的例子。
我并不一定讨厌class,但使用class的90%的理由是为了获得继承,虽然偶尔会有帮助,但经常会非常痛苦。

class Person { } 


class ArmedPerson extends Person { 
    constructor (details) { 
    super(details); 
    const gun = new Gun(); 
    this.equipment = { gun }; 
    } 

    attack (target) { 
    this.equipment.gun.fireAt(target); 
    } 
} 


class Civilian extends Person { } 


class ArmedCivilian extends ArmedPerson { 
    /* ... shouldn't it be extending Civilian? 
    Maybe all Civilians should be armed? 
    Is this why most games take place in the US? 
    */ 
} 


class Soldier extends ArmedPerson { 
    constructor (personDetails) { 
    super(personDetails); 
    } 
} 


class UnarmedSoldier extends Soldier { 
    /* HOW DO I TAKE HIS GUN AWAY? */ 
    constructor (personDetails) { 
    super(personDetails); 
    } 
    attack() { 
    /* I know he has a gun, and anybody hacking the game can use it, but what do I do here? */ 
    } 
} 

class继承已表明自己是的,人们已经非常滥用的事情之一,在过去的30多年(就像所有其他有用的工具,在那里)。

不是继承,我们可以看成分(通过依赖倒置)。

class Soldier { 
    constructor (personDetails, gun) { 
    /*...setup...*/ 
    this.equipment = { gun }; 
    this.selectedWeapon = gun; 
    } 

    attack (target) { 
    this.selectedWeapon.fireAt(target); 
    } 
} 


const soldier = new Soldier({ /*...details... */ }, new Gun()); 

不是发生了很多变化,在最终的结果,我们希望......我们已经能够真正简化了很多方面,现在我们甚至可以给他,如果换枪的方法,我们所有这些都是因为,而不是把枪拴在他继承的东西上,当我们第一次见到他的时候,我们就把枪交给他。 它可以是我们想要的任何类型的枪,只要它仍然可以以类似的方式发射。

问题出现了: 是否有更好的方法使得事物可重用,那么,如果继承完全不在表格中?

对此,我说:继承不应该完全摆脱桌面......它应该离得太远以至于它应该是一个“aha”时刻,当你发现它真的是完成某些事情的最好和最干净的方式(而不是试图从......继承一些东西,任何东西,现在!)。

各种语言都有一个概念,称为Traits或Mix-Ins。
在像Java这样的东西中,近似值近似值是Interfaces。
我不是界面的巨大粉丝(结构,而不是概念 - 热爱这个概念)。
在Java中,Interfaces使你可以做更多的工作,因为他们定义了函数,函数需要什么,返回的结果......但是你不能给它任何默认行为(传统上),所以如果你有14个实现相同接口的对象,那么你写出14次的方法(加上接口的签名)。有时候,这些方法在执行细节方面将会完全不同;没关系......有时候,它们将与您在开始编写界面时的意图完全相同。

这不太好。队列特征;这些是你定义接口的东西,定义行为,然后复制到你的对象上。 在JS中,我们甚至可以通过注入他们可以使用的上下文,而不是让他们假设他们会混淆整个this,从而在他们周围实现一些关闭安全。

const Movable = (pos) => ({ 
    up (distance) { pos.y += distance; }, 
    down (distance) { pos.y -= distance; }, 
    left (distance) { pos.x -= distance; }, 
    right (distance) { pos.x += distance; } 
}); 


class Point { 
    constructor (x, y) { 
    Object.assign(this, { x, y }); 
    } 
} 

class Person { 
    constructor (position) { 
    Object.assign(this, { position }, Movable(position)); 
    } 
} 


const person = new Person(new Point(0, 0)); 

person.up(20); 
person.position.y; // 20 

如果你会注意到,移动的可返回一个对象的新实例,与改变position值的方法。该对象将其方法复制到人的实例上。

我现在可以根据需要创建尽可能多的这些Traits,并将它们复制到我想要的任意多个对象上,然后以这种方式获得重用。

+1

谢谢!这是非常周到的 - 我将不得不思考一下... –

+1

ArmedCivilian评论大声笑,很好的解释顺便说一句。 – user2875289