问题:在不修改下面代码的情况下,如何修改 obj 对象?
var o = (() => {
var obj = {
a: 1,
b: 2,
};
return {
get: (n) => {
return obj[n];
},
};
})();
思路:尝试拿到 obj 对象本身。
方法1:通过 valueOf 方法
Object.prototype.valueOf()方法返回:转换成对象的 this 值。
var o = (() => {
var obj = {
a: 1,
b: 2,
};
return {
get: (n) => {
return obj[n];
},
};
})();
console.log(o.get("valueOf")());
// Uncaught TypeError: Cannot convert undefined or null to object
// 报错;此时调用 valueOf 的不是 obj,this 指向不是 obj
方法2:通过 Object.defineProperty() 给对象原型添加一个访问器属性
var o = (() => {
var obj = {
a: 1,
b: 2,
};
return {
get: (n) => {
return obj[n];
},
};
})();
Object.defineProperty(Object.prototype, "xxx", {
get() {
return this;
},
});
const obj2 = o.get("xxx");
console.log(obj2); // {a: 1, b: 2}
obj2.a = 100;
console.log(o.get("a")); // 100
解决该漏洞的方法
var o = (() => {
// 1. 将 obj 对象的原型链切断
// obj = Object.create(null) 或 Object.setPrototypeOf(obj, null)
var obj = {
a: 1,
b: 2,
};
return {
get: (n) => {
// return obj[n];
// 2. 判断是否是该对象自身的属性
if (obj.hasOwnProperty(n)) {
return obj[n];
}
},
};
})();