如何使用js es5 Object.defineProperty重载=运算符

时间:2015-08-22 19:00:16

标签: javascript defineproperty

我使用=为JS对象重载Object.defineProperty运算符。

var log = console.log.bind(console);
var obj = { };
Object.defineProperty(obj,'var', {
  get: function() { log('get'); return obj._var; },
  set: function(v) { log('set'); obj._var = v; }
});

这是用于定义简单属性的标准es5语法 现在obj.var是一个重载=运算符的属性 但实际上我要做的是为=本身重载obj运算符。

obj.var = 'a'; // prints: get
var v = obj.var;
v = 'b';  // prints: nothing!
// of course that's right, because v is an string now.

如何为对象本身重载=运算符?

//i what something like this 
v = 'b'; // should print: set

是否可以(在es5中)?

2 个答案:

答案 0 :(得分:2)

不,这是不可能的。事实上,你没有超载=运算符,你正在重载.运算符(或者一般的属性访问器)。只要使用对象的属性,就会调用getter / setter。 v不再是属性,它只是一个包含值的变量。

尽管如此,虽然你不能为任意变量做这个,但是with statement确实允许你编写看起来像变量赋值的代码,并按照你的预期行事:

with({
  get v() { console.log("get"); return 5; },
  set v(x) { console.log("set", x); }
}) {
  v = 5; // set 5
  console.log(v); // get, 5
}

请注意,这真的很可怕,你真的不应该这样做。它有充分理由被禁止使用严格模式。

答案 1 :(得分:1)

  

您可以将属性描述符复制到另一个对象上,但这可能会产生意外结果,具体取决于引用的方式(例如,您引用obj._var,但类似的实现可以使用this._var或闭包) - 保罗S。

  

@PaulS。你能给我举个例子吗。谢谢。 - 阿明

说你已经设定了你的定义

var log = console.log.bind(console);
var obj = { };
Object.defineProperty(obj,'var', {
  get: function() { log('get'); return obj._var; },
  set: function(v) { log('set'); obj._var = v; }
});

现在将描述符复制到另一个 Object

var o2 = {}; // another object
Object.defineProperty(
    o2, 'copied_var',
    Object.getOwnPropertyDescriptor(obj, 'var')
);

然后,您可以通过此不同对象

使用这些getter和setter
o2.copied_var = 1; // logs set
o2.copied_var;    // 1, logs get

但请注意,因为函数中的引用是obj._var我们有

o2._var; // undefined
obj._var; // 1
obj.var; // 1 (same lookup), logs get