闭包 && 原型变态真题

在不修改以下代码的前提下,如何修改person对象

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拦截方法,进而从中可找到破解该题的方法

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时候,返回其本身:

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 }

从上述代码可知,就是利用了原型的这么一个漏洞解决这个问题,那么问题来了,如何解决这个漏洞,获取对象属性的时候,判断下该属性是不是自由属性而非原型上的属性,上代码:

const obj = (function () {
    const person = {
        name: "Jerry",
        age: 18,
    }
    return {
        get: function (key) {
            if (Object.hasOwnProperty(key)) {
                return person[key];
            }
            return undefined;
        }
    }
})()

或者,定义对象时候规定对象没有原型

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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值