2016-03-21 31 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