我认为我不了解整个原型流程,我有这个问题:
function SomeO() {};
SomeO.prototype.arr = [];
SomeO.prototype.str = "";
var s1 = new SomeO();
var s2 = new SomeO();
s1.str+="1"
console.log(s2) // "" OK
s1.arr.push(1)
console.log(s2) // [1] WHY???
为什么当我在一个对象中向一个数组中添加一个项目时,它具有相同的数组实例?
答案 0 :(得分:2)
那是因为对象是由“SomeO”对象的所有实例引用共享的,在这种情况下是你的“arr”属性,而字符串或数字之类的东西是由值共享的,所以对字符串的修改不会影响其他实例的价值。
所以在这种情况下获得该结果是正常的。
function SomeO() {};
SomeO.prototype.arr = [];
SomeO.prototype.str = "chimichangas";
var s1 = new SomeO();
var s2 = new SomeO();
s1.str+="1"
console.log(s1.str); // "chimichangas1" OK because is by value
console.log(s2.str); // "chimichangas" OK because is by value
s1.arr.push(1);
console.log(s2.arr); // [1] WHY??? because is by reference
如果您不想共享阵列,则应该执行类似的操作。
function SomeO() {
this.arr = [];
};
SomeO.prototype.str = "";
var s1 = new SomeO();
var s2 = new SomeO();
s1.str+="1"
console.log(s1.str); // "1" OK
console.log(s2.str); // "" OK
s1.arr.push(1);
console.log(s1.arr); // [1] Ok
console.log(s2.arr); // [] Ok
答案 1 :(得分:0)
由于两个实例共享相同的[[Prototype]]
(分配给SomeO.prototype
的对象),因此也会在SomeO.prototype.arr
中共享相同的数组。
您可以自己查看:
s1.arr === s2.arr
为了避免这种情况,您可以在构造函数中定义数组(以及您可能需要的所有其他对象):
function SomeO() {
this.arr = [];
this.obj = {}; // define all arrays and objects in the constructor if they need to be separate
}
答案 2 :(得分:0)
因为你是如何定义数组的:你在原型上创建一个数组对象,它在所有实例之间共享。通常,您只想在原型上放置函数和常量值。每个实例属性都需要在构造函数中创建:
function SomeO() {
this.arr = [];
}
答案 3 :(得分:0)
当你引用一个对象的属性(例如s1.arr
)时,它首先检查该对象上是否存在该属性,如果它存在,则返回该属性,如果不存在,则返回到对象的原型。
当您执行s1.str += "1"
(等同于s1.str = s1.str + "1"
)时,您在对象本身上设置了str
属性,原型的str
属性不会更改。 s1.str
将从s1
返回新字符串,s2.str
将返回prototype.str
。
s1's str s2's str prototype's str s1.str s2.str
before: - - "" "" (from proto) "" (from proto)
after: "1" "" "1" (from own) "" (from proto)
当您执行s1.arr.push(1)
时,您会从原型获得s1.arr
,并更改其值。您从未在arr
上设置s1
属性。
s1's arr s2's arr prototype's arr s1.arr s2.arr
before: - - [] [] (from proto) [] (from proto)
after: - - [1] [1] (from proto) [1] (from proto)