Open kangduu opened 1 year ago
为什么 valueOf 无法获取 source ?
首先,我们获取data的valueOf值
data.get('valueOf') // [Function: valueOf]
可以看到是一个函数,对吧,好的直接执行啦?
data.get('valueOf')()
咦?为什么不行啦?
因为 ‘data.get('valueOf')()’ 等同于下面操作
const vo = Object.prototype.valueOf;
vo();
所以,根本原因是this指向问题。
正解:属性访问器
我们知道,访问一个属性时,是可以通过属性访问器返回的。getter
好的,下面我们使用defineProperty在现有对象上定义 getter
// 在data的原型上添加一个 _get 方法
Object.defineProperty(data.__proto__, '_get', {
// 将这个属性变为一个访问器
// 之后读取这个属性,就会执行get这个函数
get() {
// 直接返回this
return this;
},
});
console.log(data.get('_get'));
完美,成功获取到闭包中的对象了。
const source = data.get('_get');
source.b = 100;
console.log(data.get('b')); // 100
source.b = 10;
console.log(data.get('b')); //10
如何预防?
A计划 在函数中验证,确定属性是其本身,不是原型上的
let data = (function () {
let source = {
a: 10,
b: 99,
};
return {
get: function (key) {
if (!source.hasOwnProperty(key)) return undefined; //【*】
return source[key];
},
};
})();
B计划 将source的原型设为null,前提是source不需要原型上的任何东西。
let data = (function () {
let source = {
a: 10,
b: 99,
};
Object.prototype(source, null); // 【*】
return {
get: function (key) {
return source[key];
},
};
})();
你是否认为第三方库的代码是不可更改的?你是否认为闭包可以保护内部对象的完整性?
请问,在不修改上面代码的情况下,如何修改source对象?