在Javascript中,为什么要将引用类型的实例变量放在构造函数中?

在Javascript中,为什么要将引用类型的实例变量放在构造函数中?,javascript,constructor,prototype,Javascript,Constructor,Prototype,阅读Google developer insights的摘录: 对于具有值类型(而不是引用类型)初始化值的实例变量(即类型为number、Boolean、null、undefined或string的值),将实例变量声明/初始化放置在原型上。这样可以避免每次调用构造函数时不必要地运行初始化代码。(对于初始值依赖于构造函数参数的实例变量,或构造时的其他状态,无法执行此操作。) 例如,代替: foo.Bar = function() { this.prop1_ = 4; this.prop

阅读Google developer insights的摘录:


对于具有值类型(而不是引用类型)初始化值的实例变量(即类型为number、Boolean、null、undefined或string的值),将实例变量声明/初始化放置在原型上。这样可以避免每次调用构造函数时不必要地运行初始化代码。(对于初始值依赖于构造函数参数的实例变量,或构造时的其他状态,无法执行此操作。)

例如,代替:

foo.Bar = function() {
  this.prop1_ = 4;
  this.prop2_ = true;
  this.prop3_ = [];
  this.prop4_ = 'blah';
};
foo.Bar = function() {
  this.prop3_ = [];
};

foo.Bar.prototype.prop1_ = 4;

foo.Bar.prototype.prop2_ = true;

foo.Bar.prototype.prop4_ = 'blah';
使用:

foo.Bar = function() {
  this.prop1_ = 4;
  this.prop2_ = true;
  this.prop3_ = [];
  this.prop4_ = 'blah';
};
foo.Bar = function() {
  this.prop3_ = [];
};

foo.Bar.prototype.prop1_ = 4;

foo.Bar.prototype.prop2_ = true;

foo.Bar.prototype.prop4_ = 'blah';


我理解将具有值类型的变量放入函数原型的逻辑,但是当我们有这样一个引用变量时,我们不是在运行初始化代码吗;(根据谷歌的例子)?这不是在每次调用构造函数时都会创建一个新数组吗?

引用类型的实例属性需要添加到构造函数中,否则添加到原型时,构造对象的每个实例都将共享相同的引用。仅仅阅读信息是可以的,但修改时会出现问题。请检查以下示例

var Test = function () {
    this.foo = [];
};

Test.prototype.bar = [];

var instance1 = new Test();
var instance2 = new Test();

instance1.foo.push(1);
instance1.bar.push(1);
instance2.foo.push(2);
instance2.bar.push(2);

console.log(instance1.foo, instance1.bar); // [1], [1,2]

尽管只调用了一次
instance1.bar.push
,但数组有两个值,因为
instance1.bar
instance2.bar
是同一个数组,由两个对象共享。

“这不是每次调用构造函数都会创建一个新数组吗?”-是的,这就是重点。没有“引用类型”或“值类型”。中列出了有效的语言类型。变量有一个值,该值可能是a或引用(aka)。