我想尝试一下 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.prototype
或
instance.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