0

我使用什么来重载=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 语法。
Nowobj.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 中)吗?

4

2 回答 2

2

不,这是不可能的。实际上,您并没有重载=运算符,而是重载了.运算符(或一般的属性访问器)。每当使用对象的属性时,都会调用您的 getter / setter 。v不再是属性,它只是一个保存值的变量。


也就是说,虽然您不能对任意变量执行此操作,但该with语句确实允许您编写看起来像变量赋值的代码并执行您的预期:

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

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

于 2015-08-22T22:14:31.213 回答
1

您可以将属性描述符复制到另一个对象上,但这可能会产生意想不到的结果,具体取决于引用事物的方式(例如,您引用obj._var,但可以使用类似的实现this._var或闭包) – Paul 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
于 2015-08-22T21:33:01.707 回答