在不修改以下代码的前提下,如何修改person对象
代码语言:javascript复制const obj = (function () {
const person = {
name: "Jerry",
age: 18,
}
return {
get: function (key) {
return person[key];
}
}
})()
console.log('name--obj:', obj.get('name')); // Jerry
console.log('name--obj:', obj.get('age')); // 18
console.log('name--obj:', obj.get('address')); // undefined
通过以上代码可知,obj是个立即执行函数,内部一个闭包person,该立即执行函数返回了读取person对象的方法。
根据原型可知,当自身没有没有某个属性/方法时,就会往原型上查找,同时再运用object的get拦截方法,进而从中可找到破解该题的方法
代码语言:javascript复制Object.defineProperty(Object.prototype, 'sex', {
get: function () {
return {
name: "Kitty",
age: 32,
sex: "Male",
};
}
})
console.log('sex--obj:', obj.get('sex')); // { name: 'Kitty', age: 32, sex: 'Male' }
当然,上述代码多少有点暴力,可简单优化下,每次访问Object时候,返回其本身:
代码语言:javascript复制Object.defineProperty(Object.prototype, 'sex', {
get: function () {
return this;
}
})
const newObj = obj.get('sex');
newObj.sex = 'Boy'; // 不会新增属性
newObj.name = 'Tom';
console.log('sex--obj:', obj.get('sex')); // { name: 'Tom', age: 18 }
从上述代码可知,就是利用了原型的这么一个漏洞解决这个问题,那么问题来了,如何解决这个漏洞,获取对象属性的时候,判断下该属性是不是自由属性而非原型上的属性,上代码:
代码语言:javascript复制const obj = (function () {
const person = {
name: "Jerry",
age: 18,
}
return {
get: function (key) {
if (Object.hasOwnProperty(key)) {
return person[key];
}
return undefined;
}
}
})()
或者,定义对象时候规定对象没有原型
代码语言:javascript复制const obj = (function () {
const person1 = {
name: "Jerry",
age: 18,
}
// Object.setPrototypeOf(person, null); // 方法一
const person = Object.create(null, { // 方法二
name: {
value: "Jerry",
},
age: {
value: 18,
}
})
return {
get: function (key) {
return person[key];
}
}
})()