Mar*_*icu 7 javascript prototype function-prototypes javascript-objects
我想对Proxy对象进行一些试验,并得到了一些意外的结果,如下所示:
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`;
};
Run Code Online (Sandbox Code Playgroud)
因此,在跟踪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`;
};
Run Code Online (Sandbox Code Playgroud)
The property: "farewell" has been updated with: "function () {
return `Hello my name is ${this.first} and I will see you later`;
}"
Run Code Online (Sandbox Code Playgroud)
没什么
当然,我每次添加或删除的东西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`;
}"
Run Code Online (Sandbox Code Playgroud)
Person.prototype
Proxy {greeting: ƒ, first: "George", last: "Clooney", age: 55, farewell: ƒ, constructor: ƒ}
Run Code Online (Sandbox Code Playgroud)
它在上设置了所有属性,在prototype实例上没有设置任何属性,而每次我在上instance设置内容时,它都直接在上设置了属性prototype。
显然,这不是默认的行为,就像我删除了一样Proxy,每个with this设置的属性都将在实例本身上设置,并且prototype将开始为空(或者在我们的情况下仅使用该greeting函数)。
我在这里想念什么?在正确方向上的一点将不胜感激。
您缺少的事实是,当原型链中有一个Proxy对象时,修改子对象时将调用set处理程序。
在您的示例中,当您在新实例上设置属性时,将执行set陷阱,该陷阱将是target包装的Person.prototype对象,但是还有第四个参数receiver。此参数指向已访问该属性的对象。
要正确进行属性分配,可以使用Reflect.setAPI进行设置:
Reflect.set(target, key, value, receiver);
Run Code Online (Sandbox Code Playgroud)
这就是ReflectAPI与代理陷阱参数匹配的原因。
因此,在您的示例中,我们可以使用Reflect API,您将看到Person.prototype它不会被“污染”。
Reflect.set(target, key, value, receiver);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
93 次 |
| 最近记录: |