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

how to overload = operator with js es5 Object.defineProperty

我要使用 Object.defineProperty.

为 JS 对象重载 = 运算符
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 中)?

You can copy the property descriptor onto another object, but this may give unexpected results depending on how things are referenced (e.g. you reference obj._var, but a similar implementation could use this._var or a closure) – Paul S.

@PaulS. can you give an example. thanks. – amin

假设您设置了定义

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')
);

然后你可以通过这个不同的对象

使用这些getters和setters
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

不,这是不可能的。实际上,您没有重载 = 运算符,而是重载了 . 运算符(或一般的 属性 访问器)。只要您的对象的 属性 被使用,您的 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
}

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