• 闭包——破坏第三方库


    闭包

    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
  • 相关阅读:
    中级深入--day15
    PHPhotoLibrary 获取相册权限注意事项
    C语言《认识结构体》---重点解析内存对齐
    30 C++ 预处理器
    Pytorch-YOLOv4梳理——原理和复现
    小程序商城上线需要做什么?
    python中scipy中uniform分布怎么用
    数据代理-Object.defineProperty -Vue中的数据代理
    图神经网络GNN(一)GraphEmbedding
    SpringBoot中间件简介
  • 原文地址:https://blog.csdn.net/weixin_45678402/article/details/132922608