闭包问题优化

文章目录

      • 1、闭包基本实现
      • 2、问题简述
      • 3、优化
        • 3.1 空原型链或
        • 3.2 限定key范围

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 限定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()

你可能感兴趣的:(web,前端,javascript,前端,typescript)