闭包问题优化

1、闭包基本实现

/**
 * 让外部方法使用内部局部变量,防止全局变量被污染;
 * 但仅限于使用,不建议对局部变量进行修改
 */
const obj = function() {
  let o = {
    name: "zhangsan",
    age: "18"
  }
  return function (key) {
    return o[key];
  }
} ()

console.log(obj("age"));      // 18

2、问题简述

上述方式并不能完全实现闭包,可以通过原型链拿取对象信息并加以修改

// 在原型上添加方法,获取当前对象,并能修改对象内部name属性的值
Object.defineProperty(Object.prototype,'getAll', {
  // 访问该属性时,将不带参地调用此函数,**并将 this 设置为通过该属性访问的对象**
  get() {
    return this;
  },
  // 当该属性被赋值时,将调用此函数,并带有一个参数(要赋给该属性的值)
  // **并将 this 设置为通过该属性分配的对象**
  set(value) {
    this["name"] = value;
  }
})

// 获取对象信息
console.log(obj("getAll"));  // { name: 'zhangsan', age: '18' }
// 修改对象内容
obj("getAll").getAll = "lisi";
console.log(obj("getAll"));  // { name: 'lisi', age: '18' }

3、优化

3.1 空原型链
const obj = function() {
  // 指定原型链为null(参数只能为 null 或 Object)
  let o = Object.create(null);
  o.name = "zhangsan",
  o.age = "18";
  return function (key) {
    return o[key];
  }
} ()

// 验证原型链
Object.defineProperty(Object.prototype,'getAll', {
  get() {
    return this;
  }
})
console.log(obj("getAll"));  // undefined
3.2 断开原型链(原有Object链上的方法无法使用-不建议
const obj = function() {
  let o = {
    name: "zhangsan",
    age: "18"
  }
  o.prototype = null;
  return function (key) {
    return o[key];
  }
} ()
3.3 限定key范围
const obj = function() {
  let o = {
    name: "zhangsan",
    age: "18"
  }
  return function (key) {
    // 判断是否是对象自有属性,非继承属性;可用 Object.hasOwn(对象名,属性名) 代替
    if(o.hasOwnProperty(key)) {
      return o[key];
    }
    throw new Error("key is not exist!")
  }
} ()
// 验证原型链
Object.defineProperty(Object.prototype,'getAll', {
  get() {
    return this;
  },
})

console.log(obj("getAll"));  // Error: key is not exist!

PS. Object.hasOwn() 旨在取代 Object.prototype.hasOwnProperty()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值