原型数组参数

Prototype array param

我认为我没有理解整个原型流程,我有这个问题:

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???

为什么当我将一个项目添加到一个对象中的数组时,它具有相同的数组实例?

因为两个实例共享相同的 [[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
}

因为这就是您定义数组的方式:您在所有实例之间共享的原型上创建了 one 数组对象。通常,您只想将函数和常量值放在原型上。每个实例 属性 都需要在构造函数中创建:

function SomeO() {
    this.arr = [];
}

当你引用一个对象的属性时(例如s1.arr),它首先检查对象上是否存在属性,如果存在,它return是它,如果不是,它会回退到对象的原型。

当您执行 s1.str += "1" 时,相当于 s1.str = s1.str + "1",您是在对象本身上设置 str 属性,原型的 str 属性不变。 s1.str 将 return 来自 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,并更改其值。你永远不会在 s1.

上设置 arr 属性
          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)

那是因为你的 "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