原型数组参数

时间:2016-03-02 16:08:05

标签: javascript arrays oop prototype instance

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

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

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

4 个答案:

答案 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)