• 闭包——破坏第三方库


    闭包

    1 获取 obj 对象

    1.1 失败获取
    var o = (function () {
      var obj = {
        a: 1,
        b: 2,
      };
      return {
        getObj: function (k) {
          return obj[k];
        },
      };
      
    })();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    const res = o.getObj('a');
    console.log('===>res', res); // ===>res 1
    
    • 1
    • 2
    // 不改变上面代码的情况下,修改 obj 对象。破坏第三方库
    const resValueOf = o.getObj('valueOf');
    console.log('===>resValueOf', resValueOf); // ===>resValueOf [Function: valueOf]
    
    • 1
    • 2
    • 3

    o.getObj('valueOf')() 调用失败;原因: this 指向不对

    const resValueOfObj = o.getObj('valueOf')(); // 返回 obj 对象本身失败,原因:this指向不对
    console.log('===>resValueOfObj', resValueOfObj); // this指向有问题,会报错:TypeError: Cannot convert undefined or null to object
    
    // o.getObj('valueOf')函数的 this 指向全局,严格模式下指向undefined
    // 执行 const resValueOfObj = o.getObj('valueOf')()
    // 相当于执行
    // const valueOf = Object.prototype.valueOf;   
    // valueOf();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1.2 使用函数调用结果获取 obj 对象

    那么如何获取 obj 对象本身呢?可以这样去写

    
    var o = (function () {
      var obj = {
        a: 1,
        b: 2,
      };
      return {
        getObj: function (k) {
          return obj[k](); // 返回函数调用结果
        },
      };
    })();
    
    
    // 不改变上面代码的情况下,修改 obj 对象。破坏第三方库
    
    const resValueOfObj = o.getObj('valueOf'); // 返回 obj 对象本身
    console.log('===>resValueOfObj', resValueOfObj); // ===>resValueOfObj { a: 1, b: 2 }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    1.3 利用 defineProperty,获取 obj 对象

    不通过 “返回函数调用结果”,如何获取对象本身,并且更改 obj 对象,破坏第三方库?

    var o = (function () {
      var obj = {
        a: 1,
        b: 2,
      };
      return {
        getObj: function (k) {
          return obj[k];
        },
      };
      
    })();
    
    const res = o.getObj('a');
    console.log('===>res', res); // ===>res 1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    // 不改变上面代码的情况下,修改 obj 对象。破坏第三方库
    
    Object.defineProperty(Object.prototype, 'abc', {
      get() {
        return this;
      }
    })
    const resValueOfObj = o.getObj('abc');
    console.log('===>resValueOfObj', resValueOfObj); // ===>resValueOfObj { a: 1, b: 2 }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    修改 obj 对象;破坏第三方库

    resValueOfObj.c = 2;
    resValueOfObj.a = 'aaa';
    console.log('===>resValueOfObj.a', resValueOfObj.a); // ===>resValueOfObj.a aaa
    console.log('===>resValueOfObj.c', resValueOfObj.c); // ===>resValueOfObj.c 2
    
    console.log('===>o.getObj(a)', o.getObj('a'));  // ===>o.getObj(a) aaa
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2 防止破坏第三方库

    那么如何防止破坏第三方库呢?或者说在写公共模块时,如何防止破坏呢?

    2.1 利用 hasOwnProperty

    var o = (function () {
      var obj = {
        a: 1,
        b: 2,
      };
      return {
        getObj: function (k) {
          if (obj.hasOwnProperty(k)) {
            return obj[k];
          }
          return undefined;
        },
      };
      
    })();
    
    const res = o.getObj('a');
    console.log('===>res', res); // ===>res 1
    
    
    Object.defineProperty(Object.prototype, 'abc', {
      get() {
        return this;
      }
    })
    const resValueOfObj = o.getObj('abc');
    console.log('===>resValueOfObj', resValueOfObj); // ===>resValueOfObj undefined
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    2.2 将 obj 对象的原型设为 null

    Object.setPrototypeOf(obj, null)

    var o = (function () {
      var obj = {
        a: 1,
        b: 2,
      };
    
      Object.setPrototypeOf(obj, null); // 将 obj 对象的原型设为 null
      return {
        getObj: function (k) {
          return obj[k];
        },
      };
      
    })();
    
    const res = o.getObj('a');
    console.log('===>res', res); // ===>res 1
    
    
    Object.defineProperty(Object.prototype, 'abc', {
      get() {
        return this;
      }
    })
    const resValueOfObj = o.getObj('abc');
    console.log('===>resValueOfObj', resValueOfObj); // ===>resValueOfObj undefined
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
  • 相关阅读:
    应用商店备案登记流程解析
    考公顺序步骤
    ERP系统如何改善企业的业务?
    【Linux】OS和进程概念
    可见性检测-unity掌握常见的可见性检测算法实现原理
    QT - 简易画板
    面试题:你是如何计划和组织一个大型的软件测试项目的?
    大语言模型之十二 SentencePiece扩充LLama2中文词汇
    el-table 懒加载自动展开节点
    【优化算法】加权黑猩猩优化算法(WChOA)(Matlab代码实现)【与ChOA、PSO、WOA、BH、ALO、GA和GWO算法比较】
  • 原文地址:https://blog.csdn.net/weixin_45678402/article/details/132922608