我想尝试一下 Proxy object ,得到了一些意想不到的结果,如下:

测试脚本

function Person(first, last, age) { 
  this.first = first; 
  this.last = last; 
  this.age = age; 
} 
 
Person.prototype.greeting = function () { 
  return `Hello my name is ${this.first} and I am ${this.age} years old`; 
}; 

所以在跟踪 prototype对象正在修改,我添加了这个包装器:
let validator = { 
    set: function(target, key, value) { 
        console.log(`The property ${key} has been updated with ${value}`); 
        target[key] = value; 
        return true; 
    } 
}; 
 
Person.prototype = new Proxy(Person.prototype, validator); 
 
let george = new Person('George', 'Clooney', 55); 
 
Person.prototype.farewell = function () { 
  return `Hello my name is ${this.first} and I will see you later`; 
}; 

我所期望的
The property: "farewell" has been updated with: "function () { 
  return `Hello my name is ${this.first} and I will see you later`; 
}" 

没有别的了。

当然,每次我在 prototype 中添加或删除某些内容时, ,即 Person.prototypeinstance.constructor.prototype我希望看到 console.log()信息。

不过我 没有在实例上设置某些东西时期望看到任何东西,例如:
george.someProp = 'another value'; // did NOT expect to see the console.log()
输出
The property: "first" has been updated with: "george" 
The property: "last" has been updated with: "clooney" 
The property: "age" has been updated with: "55" 
The property: "farewell" has been updated with: "function () { 
  return `Hello my name is ${this.first} and I will see you later`; 
}" 
Person.prototype 
Proxy {greeting: ƒ, first: "George", last: "Clooney", age: 55, farewell: ƒ, constructor: ƒ} 

它设置了 prototype上的所有属性实例上什么都没有,每次我在 instance 上设置一些东西它直接设置在 prototype .

显然这不是默认行为,好像我删除了 Proxy , 每个属性都设置为 this将在实例本身和 prototype 上设置将开始为空(或者在我们的例子中只有 greeting 函数)。

我在这里想念什么?正确方向的一点将不胜感激。

请您参考如下方法:

您缺少的是当您在原型(prototype)链中有一个 Proxy 对象时,当您修改子对象时将调用 set 处理程序。

在您的示例中,当您在新实例上设置属性时,将执行设置陷阱,target将被包裹 Person.prototype对象,但 还有第四个参数,receiver .此参数指向已访问该属性的对象。

要正确进行属性分配,您可以使用 Reflect.set设置它的 API:

Reflect.set(target, key, value, receiver); 

这就是为什么 Reflect API 匹配代理陷阱参数。

因此,在您的示例中,我们可以使用 Reflect API,您将看到 Person.prototype不会被“污染”。

function Person(first, last, age) { 
  this.first = first; 
  this.last = last; 
  this.age = age; 
} 
 
Person.prototype.greeting = function () { 
  return `Hello my name is ${this.first} and I am ${this.age} years old`; 
}; 
 
 
const validator = { 
    set: function(target, key, value, receiver) { 
        console.log(`The property ${key} has been updated with ${value}`); 
        Reflect.set(target, key, value, receiver) 
        return true; 
    } 
}; 
 
Person.prototype = new Proxy(Person.prototype, validator); 
 
const george = new Person('George', 'Clooney', 55); 
 
Person.prototype.farewell = function () { 
  return `Hello my name is ${this.first} and I will see you later`; 
}; 
 
console.log(george.hasOwnProperty('first')); // true 
console.log(Person.prototype.hasOwnProperty('first')); // false


评论关闭
IT干货网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!