我正在运行两项测试来检查对象在javascript中的工作方式:
测试一个:
//Method 1
var Player = {
name: "",
id: "",
action: {
action1: "",
action2: "",
action3: ""
}
}
var player1 = Object.create(Player);
player1.name = " hack";
player1.id = 1;
player1.action.action1 = "aaa";
player1.action.action2 = "aaa";
player1.action.action3 = "aaa";
console.log(JSON.stringify(player1.action));
var player2 = Object.create(Player);
player2.name = " Jason";
player2.id = 2;
player2.action.action1 = "bbb";
player2.action.action2 = "bbb";
player2.action.action3 = "bbb";
console.log(JSON.stringify(player2.action));
console.log(JSON.stringify(player1.action));

结果是:
{"action1":"aaa","action2":"aaa","action3":"aaa"}
VM174:29 {"action1":"bbb","action2":"bbb","action3":"bbb"}
VM174:30 {"action1":"bbb","action2":"bbb","action3":"bbb"}
您可以通过创建player2来更改播放器1的操作对象。
如果我希望操作对象保留它的值,该怎么办?
我能想到的唯一方法是:
//Medthod 2
var actionManager = {
action1: "",
action2: "",
action3: ""
}
var Player = {
name: "",
id: "",
action: null
}
var player1 = Object.create(Player);
var actions1 = Object.create(actionManager);
actions1.action1 = "aaa";
actions1.action2 = "aaa";
actions1.action3 = "aaa";
player1.name = " hack";
player1.id = 1;
player1.action = actions1;
console.log(JSON.stringify(player1));
var player2 = Object.create(Player);
player2.name = " Jason";
player2.id = 2;
var actions2 = Object.create(actionManager);
actions2.action1 = "bbb";
actions2.action2 = "bbb";
actions2.action3 = "bbb";
player2.action = actions2;
console.log(JSON.stringify(player2));
console.log(JSON.stringify(player1));

在这种情况下,输出为:
{"name":"hack","id":1,"action:{"action1":"aaa","action2":"aaa","action3":"aaa"}}
{"name":" Jason","id":2,"action:{"action1":"bbb","action2":"bbb","action3":"bbb"}}
{"name":" hack","id":1,"action":{"action1":"aaa","action2":"aaa","action3":"aaa"}}
有没有更好的方法来使用方法1,但是不要更改操作对象?
答案 0 :(得分:0)
有没有更好的方法来使用方法1,但是不要更改操作对象?
使用构造函数为您初始化action
属性,这样您就不必手动将其写出来。您无法避免needing them,除非您将它们展平并将.action*
直接放在播放器上。
答案 1 :(得分:0)
由于在Javascript中替换Array或Object时,Javascript会引用数组/对象而不是复制。
因此,当您执行player1.action.action1 = "aaa";
或player2.action.action1 = "bbb";
时,您正在更改Player
值的值。因为player1或player2只是指向Player
对象。
Object.create()方法使用指定的原型对象和属性创建一个新对象。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create
表示您正在创建一个与Array / Object具有相同引用的新对象。因为即使Player
没有Array作为其属性,也没有对Array / Object的内存地址的引用。所以Object.create()
创建的新对象也只有引用。
如果您检查播放器对象的内容,您会注意到它的值也已更改。
console.log(Player)
action:
action1: "bbb"
action2: "bbb"
action3: "bbb"
要避免这种情况。当您将对象用作原型时,需要深度复制对象。
//Method 1
var Player = {
name: "",
id: "",
action: {
action1: "",
action2: "",
action3: ""
}
}
objectCreate = function(obj){
return jQuery.extend(true, {},obj)
};
var player1 = objectCreate(Player);
player1.name = " hack";
player1.id = 1;
player1.action.action1 = "aaa";
player1.action.action2 = "aaa";
player1.action.action3 = "aaa";
console.log(JSON.stringify(player1.action));
var player2 = objectCreate(Player);
player2.name = " Jason";
player2.id = 2;
player2.action.action1 = "bbb";
player2.action.action2 = "bbb";
player2.action.action3 = "bbb";
console.log(JSON.stringify(player2));
console.log(JSON.stringify(player1));
console.log(Player)
你需要jQuery
objectCreate = function(obj){
return jQuery.extend(true, {},obj)
};
这为您提供了完美的深度复制对象。 并且上面的代码按预期工作。
请在此处查看jQuery.extend详细信息http://api.jquery.com/jquery.extend/
答案 2 :(得分:0)
这里的问题是两个玩家共享与原型相同的Player
对象。当一个玩家改变这个对象中的字段时,它们也会在查看另一个对象时被更改。
您可以使用构造函数:
// constructor function
function Player () {
this.name = "";
this.id = "";
this.action = {
action1: "",
action2: "",
action3: ""
};
}
var player1 = new Player();
player1.name = " hack";
player1.id = 1;
player1.action.action1 = "aaa";
player1.action.action2 = "aaa";
player1.action.action3 = "aaa";
console.log(JSON.stringify(player1.action));
var player2 = new Player();
player2.name = " Jason";
player2.id = 2;
player2.action.action1 = "bbb";
player2.action.action2 = "bbb";
player2.action.action3 = "bbb";
console.log(JSON.stringify(player2.action));
console.log(JSON.stringify(player1.action));
当您调用new Player()
时,会实例化一个新对象,并为此对象创建name
和id
等新属性,而Player
的多个实例将不会相互冲突。
答案 3 :(得分:0)
Object.create
的作用是,它将一个对象作为输入并将其所有属性复制到新对象。现在,如果属性指向可变值,您将能够使用新创建的对象对其进行变异。因此,您可以使用任何指向其值的Player.action
和player1.action
的引用变量来改变player2.action
的值。
根据你的代码Player
应该是一个类而不是一个对象。因此,我们可以使它成为构造函数(JS不具有类,但具有对象构造函数),如下所示。
//New Method 1
var Player = function() {
this.name = "";
this.id = "";
this.action = {
action1: "",
action2: "",
action3: ""
};
};
var player1 = new Player(); // Create a new object using `Player` constructor function
player1.name = " hack";
player1.id = 1;
player1.action.action1 = "aaa";
player1.action.action2 = "aaa";
player1.action.action3 = "aaa";
console.log(JSON.stringify(player1.action));
var player2 = new Player(); // Create another object using `Player` constructor function
player2.name = " Jason";
player2.id = 2;
player2.action.action1 = "bbb";
player2.action.action2 = "bbb";
player2.action.action3 = "bbb";
console.log(JSON.stringify(player2.action));
console.log(JSON.stringify(player1.action));
此处使用构造函数player1
创建对象player2
和Player
。 new
关键字实际上启动了一个新对象。在传统的OOP意义上,您可以说使用player1
关键字创建了player2
和Player
类new
对象。
输出将是
{"name":"hack","id":1,"action":{"action1":"aaa","action2":"aaa","action3":"aaa"}}
{"name":" Jason","id":2,"action":{"action1":"bbb","action2":"bbb","action3":"bbb"}}
{"name":" hack","id":1,"action":{"action1":"aaa","action2":"aaa","action3":"aaa"}}