不共享状态的Mixin

时间:2017-10-07 03:25:21

标签: javascript state delegation

我刚刚开始了解JavaScript如何使用行为委派/组合/混合等等,我认为它非常简洁。 但是,当我使用此模式创建一个新对象时。我刚注意到 他们俩共享相同的“物品”道具。值。我们都知道JS根本就没有Class。我只是想知道,我怎样才能使用任何类来实现这种设计模式的正确方式,同时解决不同“玩家”之间的共享状态。感谢。

var Player = {
 init: function(name, level) {
  this.name = name
  this.level = level
 },
 getLevel: function() {
  return this.level
 }
}

var Inventory = {
 items: ['Wooden Sword', 'Small Potion', ...],
 addItem: function(item) {
  this.items.push(item)
 },
 removeItem: function(item) {
  var i = this.items.indexOf(item)
  if (i === -1) return
  this.items.splice(i, 1)
 }
}

// ..

var mario = Object.assign(Object.create(Player), Inventory)
mario.init('Mario', 1)
mario.addItem('Nice hat')
mario.items // ['Wooden Sword', 'Small Potion', 'Nice hat']

var luigi = Object.assign(Object.create(Player), Inventory)
luigi.init('Luigi', 1)
luigi.items // ['Wooden Sword', 'Small Potion', 'Nice hat'] ?
// Should be ['Wooden Sword', 'Small Potion']

2 个答案:

答案 0 :(得分:0)

您的变量为Invertory,但您正在使用Inventory进行创建。错字

答案 1 :(得分:0)

Object.assign不会将深度复制的结构从源分配给目标对象。因此,mario.addItem('Nice hat')已经更改了Inventory.items,它仍然是marioluigi的共享参考。在创建每个mario.items = Array.from(Inventory.items)实例后,像luigi.items = Array.from(Inventory.items)以及Player这样的穷人方法确实已经有所帮助。编写一个封装了对象创建的createPlayer工厂,Inventory组合和“克隆”/复制items会更好......

var Player = {
 init: function (name, level) {
  this.name = name
  this.level = level
 },
 getLevel: function () {
  return this.level
 }
}

var Inventory = {
 items: ['Wooden Sword', 'Small Potion'],
 addItem: function (item) {
  this.items.push(item)
 },
 removeItem: function (item) {
  var i = this.items.indexOf(item);
  if (i === -1) {
   return this.items.splice(i, 1);
  }
 }
}

function createPlayer(name, level) {
  var player = Object.assign(Object.create(Player), Inventory);
  player.items = Array.from(Inventory.items);
  player.init(name, level);
  return player;
}

var mario = createPlayer('Mario', 1);
mario.addItem('Nice hat');

console.log('mario.items : ', mario.items); // ['Wooden Sword', 'Small Potion', 'Nice hat']

var luigi = createPlayer('Luigi', 1);
console.log('luigi.items : ', luigi.items); // ['Wooden Sword', 'Small Potion']
.as-console-wrapper { max-height: 100%!important; top: 0; }