1

我想只使用该Object.create函数创建一个对象(没有任何原型,第一个参数为 null)。

我在某处读到属性决定了 JavaScript 中对象的状态,而 JavaScript 具有三种不同的属性:

  • 命名数据属性
  • 命名访问器属性
  • 内部属性

因此,当我在对象中定义函数时,我是否应该始终将其定义为named accessor property

var obj = Object.create(null, {   
     a:{
        get:function(){
           alert('jQuery nyan!');          
        }
     }
});​

或者我应该将函数定义为 anamed data property当它既不是 asetter也不是 a时getter?[例如一些对 DOM obj 进行更改的 jQuery 函数]

var obj = Object.create(null, {
     a:{
        value:function(){
              alert('jQuery nyan!');          
        }
     }
});​

我应该采取哪种方法?在性能(速度)和内存管理方面它们有区别吗?他们似乎都毫无例外地工作。

obj.a;
//output: 'jQuery nyan!'
4

2 回答 2

1

为了更容易引用它们,让我们将它们定义如下

var objA = Object.create(null, {a: {get:  function(){alert('jQuery nyan!');}}});
var objB = Object.create(null, {a: {value:function(){alert('jQuery nyan!');}}});

objA.a现在,调用vs几乎没有区别objB.a(),除了使用().

但是,有一些差异。主要区别在于您不能将参数传递给 getter,它是按原样调用的。这意味着objA.a(1,2,3)不会调用带有参数的函数1, 2, 3。它实际上会在调用抛出一个错误,假设 getter 没有返回一个Function(你实际上是在尝试这样做undefined(1,2,3))。

第二个区别要求我们记住Object.create的第二个参数接受一个描述符对象,其中包括标志writable(默认为false)。这里的区别是你不能设置writable:trueobjA.a因为“一个属性不能同时有访问器和可写或有值”。这意味着如果您希望更改 getter 的方法,则必须重新定义属性,而对于value,您可以启用使用=来更改与属性关联的方法。

此外,没有 setterobjA.a = <expr>将不会执行任何操作。

通常,您只会在以下情况下使用 getter 和 setter,value否则将其作为标准行为;

  • 轻量级计算输出
  • 验证输入(保护对象)
  • 隐藏变量以防止直接访问
  • 保留变量或属性名称可能更改的标准 API
于 2012-12-05T03:46:10.643 回答
1

如果您不关心兼容性,使用getterandsetters可能是替换setNAME()s 和getNAME()s 的好方法。与功能版本相比,没有显着的性能增益/损失

请注意,因为它看起来像访问一个变量,而不是调用一个函数,所以getter/setter函数应该是非常轻量级的以满足这个期望。

并且永远不要像 jQuery 那样对 getter 和 setter都使用一个函数,它非常慢。由于javascript中没有函数签名,因此模拟它if/else会导致大量性能损失。

于 2012-12-05T03:59:49.153 回答