不共享状态的 Mixin
A Mixin that doesn't share state
我刚刚开始了解 JavaScript 是如何与行为 Delegation/Composition/Mixins 等一起工作的,我认为它非常简洁。
但是,当我使用此模式创建新对象时。我刚注意到
他们两个共享相同的 'items' 道具。价值。我们都知道JS是真的没有Class可言。我只是想知道,如何使用任何 class 实现此设计模式 w/o 的正确方法,同时解决不同 'Players' 之间的共享状态。谢谢
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']
您的变量是 Invertory
但您正在使用 Inventory
来创建。错别字
Object.assign
不会将深度复制的结构从源对象分配给目标对象。因此 mario.addItem('Nice hat')
已经更改了 Inventory.items
,它仍然是 mario
和 luigi
的共享引用。在创建每个 Player
实例之后,像 mario.items = Array.from(Inventory.items)
和 luigi.items = Array.from(Inventory.items)
这样的穷人方法确实已经有所帮助。编写一个 createPlayer
封装对象创建、Inventory
组合和 "cloning"/复制 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; }
我刚刚开始了解 JavaScript 是如何与行为 Delegation/Composition/Mixins 等一起工作的,我认为它非常简洁。 但是,当我使用此模式创建新对象时。我刚注意到 他们两个共享相同的 'items' 道具。价值。我们都知道JS是真的没有Class可言。我只是想知道,如何使用任何 class 实现此设计模式 w/o 的正确方法,同时解决不同 'Players' 之间的共享状态。谢谢
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']
您的变量是 Invertory
但您正在使用 Inventory
来创建。错别字
Object.assign
不会将深度复制的结构从源对象分配给目标对象。因此 mario.addItem('Nice hat')
已经更改了 Inventory.items
,它仍然是 mario
和 luigi
的共享引用。在创建每个 Player
实例之后,像 mario.items = Array.from(Inventory.items)
和 luigi.items = Array.from(Inventory.items)
这样的穷人方法确实已经有所帮助。编写一个 createPlayer
封装对象创建、Inventory
组合和 "cloning"/复制 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; }