如何在原型中初始化实例变量可以提高性能

时间:2017-07-29 18:40:32

标签: javascript

Here它说:

  

在实例变量的原型上放置实例变量声明/初始化,使用值类型(而不是引用类型)初始化值(即类型号,布尔值,空值,未定义或字符串的值)。这避免了每次调用构造函数时不必要地运行初始化代码。 (对于初始值依赖于构造函数的参数或构造时的某个其他状态的变量,不能这样做。)

它给出了以下示例,而不是:

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 w.r.t的实例。第二种情况:

foo = {}
f1 = new foo.Bar()
f2 = new foo.Bar()

然后测试:

f1.prop1_ // gives 4
f1.prop1_ = 5 // changed it
f2.prop1_ // still gives 4
Object.getPrototypeOf(f1) === Object.getPrototypeOf(f2) // true

现在我的问题是:虽然f1f2共享相同的原型,但每个原型似乎都有不同的范围(附件?),因此,他们有自己的prop1_副本;这意味着发生了单独的内存分配。为什么这会带来性能提升?

2 个答案:

答案 0 :(得分:1)

它更高效,因为你没有在构造函数中运行一堆赋值代码,这应该是显而易见的。它在原型上共享相同的值,因为原型上共享任何内容。

问题是,当你读取f1.prop1_时,它会查找原型链中的值,因为f1本身没有属性{{1 }}。 但是 ,当您使用prop1_分配属性时,会直接分配给f1.prop1_ = 5对象上的属性。换句话说,赋值会在对象本身上创建属性。此后,原型值被实例属性遮蔽。这就是为什么实例会有不同的值。

这对于不可变值很好;对于像数组这样的可变值,这是一个坏主意,因为f1会改变原型上的对象而不是在单个实例上创建属性。

答案 1 :(得分:1)

没有。如果您创建两个实例,整个原型链将如下所示:

 foo.Bar.prototype {
   prop1_ :4
 }
f1{
  proto:foo.Bar.prototype
 }
 f2{
  proto:foo.Bar.prototype
 }

所以当你这样做时

f1.prop1_

它检查f1中是否存在属性(它没有),然后在原型中查找它,并计算为4.

如果你这样做

f1.prop1_ = 1;

它不会设置原型的属性,而是设置元素本身的属性:

foo.Bar.prototype {
   prop1_ :4
 }
f1{
  proto:foo.Bar.prototype
  prop1_:1
 }
 f2{
  proto:foo.Bar.prototype
 }

结果如下:

f1.prop1_ // 1
f2.prop2_ // 4 (looked up in prototype)