原型数组参数
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
我认为我没有理解整个原型流程,我有这个问题:
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