闭包 && 原型变态真题

2023-06-07 11:29:02 浏览数 (2)

在不修改以下代码的前提下,如何修改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];
        }
    }
})()

0 人点赞