2016-03-21 17 views
0

assignを使用してjavascriptのコンポジションの周りを囲むようにしています。私のベースオブジェクトのプロパティは、インスタンス間で予期せず共有されています。私は間違って何をしていますか?&Object.createを使用したJavaScriptのオブジェクト構成

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:私は...

Stat.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'の* copy *を作成しません。 –

+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年以上のために、人々はひどく誤用しているものの一つであることを自分自身を示しています。

継承ではなく、(Dependency Inversionを介して)合成を見ることができます。

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()); 

多くは、私たちは本当に多くのことを簡素化することができました...我々が望んでいた最終結果の面で、変更されている、そして今、私たちも彼に私達場合は銃を交換する方法を与えることができません彼が継承するものに銃を投げつけるのではなく、最初に彼に会うときに銃を渡しているからです。 それは、同じような方法でまだ発砲されている限り、私たちが望むどんな種類の銃でもあります。

質問があります: 継承が完全にテーブルから外れている場合、再利用可能なものを作る良い方法がありますか?

私が言っていることは、継承は完全にテーブルから外れてはいけないということです... ...それは本当に「ああ」の瞬間になるはずです。 (何か、何か、今から継承しようとするよりもむしろ!)何かを達成するための最高のクリーンな方法です。

さまざまな言語には、TraitsまたはMix-Insという概念があります。
Javaのようなものでは、近似近似はInterfacesです。
私はInterfacesの巨大なファンではありません(構造ではなくコンセプト - コンセプトが大好きです)。
Javaでは、インタフェースは関数を定義し、関数が何を返し、何を返すのかによって多くの仕事をします... ...しかし、あなたはそれをデフォルトの振る舞いに(伝統的に)与えることはできません同じインターフェースを実装する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上の値を変更する方法と、オブジェクトの新しいインスタンスを返しています。そのオブジェクトはそのメソッドをpersonのインスタンスにコピーしています。

これらの特性を必要な数だけ作成し、それらを私が望む数のオブジェクトにコピーして再利用できるようになりました。

+1

ありがとう!これは信じられないほど慎重です - 私は少し熟考しなければならないでしょう... –

+1

ArmedCivilianのコメントlol、いい説明btw。 – user2875289

関連する問題