最近的Chrome / V8版本中的对象描述符getter / setter性能

时间:2016-03-31 15:59:00

标签: javascript google-chrome v8

鉴于

var obj = {};

var _a = 1;

obj._a = 1;

obj.aGetter = function() {
  return _a;
}

obj.aSetter = function(val) {
  _a = val;
}

Object.defineProperty(obj, 'a', {
  enumerable: true,
  get: function () {
    return _a;  
  },
  set: function(val) {
    _a = val;
  }     
});

使用getter / setter函数

obj.aSetter(2);
obj.aGetter();
与直接属性访问相比,

的Chrome / V8性能会降低一些(~3x):

obj._a = 2;
obj._a;

这是可以理解的。并使用描述符getter / setter

obj.a = 2;
obj.a;

会导致Chrome (41到最新)性能下降 ~30x - 几乎与Proxy一样慢。虽然Firefox和较旧的Chrome版本使用描述符getter / setter而没有显着的性能损失。

最近Chrome / V8版本中描述符getter / setter性能的确切问题是什么?这是一个可以监控的已知问题吗?

使用Benchmark.js(jsPerf引擎)进行测量。我无法提供jsPerf测试的链接以显示差异,因为jsPerf已经严重搞砸了它的反DDoS措施,但我确信现有的可以证明这一点。

1 个答案:

答案 0 :(得分:8)

表现的变化与this Chromium issue相关(积分转至@VyacheslavEgorov)。

为避免性能问题,应使用原型。这是为什么单例类可以用于实例化一次对象的几个原因之一。

使用ES5:

var _a = 1;

function Obj() {}

Object.defineProperty(Obj.prototype, 'a', {
  enumerable: true,
  get: function () {
    return _a;  
  },
  set: function(val) {
    _a = val;
  }     
});

var obj = new Obj();
// or
var obj = Object.create(Obj.prototype);

或者使用ES6语法糖:

class Obj {
  constructor() {
    this._a = 1;
  }

  get a() {
    return this._a;
  }

  set a(val) {
    this._a = val;
  }     
}

let obj = new Obj();