最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 原来是严格模式

    正文概述 掘金(terryz95)   2021-02-28   575

    先来看这样几段代码

    function func() {
      function f() {
        return this
      }
      console.log(f())
      return f
    }
    
    func()()
    
    let obj = {
      func() {
      	function f() {
          return this
        }
        console.log(f())
        return f
      }
    }
    
    obj.func()()
    
    function T() {
    	this.func = function() {
    		function f() {
          return this
        }
        console.log(f())
        return f
    	}
    }
    
    let obj = new T()
    obj.func()()
    
    function T() {}
    T.prototype.func = function() {
      function f() {
        return this
      }
      console.log(f())
      return f
    }
    
    let obj = new T()
    obj.func()()
    
    class T {
      func() {
        function f() {
          return this
        }
        console.log(f())
        return f
      }
    }
    
    let obj = new T()
    obj.func()()
    
    class T {
      static func() {
        function f() {
          return this
        }
        console.log(f())
        return f
      }
    }
    
    T.func()()
    

    如果你将他们一一粘贴到控制台运行后会发现:除了ES6的class的两个例子外,其余的例子,嵌套函数内部函数的this都是指向全局对象window,而ES6的class的两个例子中thisundefined

    实际上上述的几个例子基本展示了大部分函数调用的方法,我们想探究的是嵌套函数内部函数的this指向什么。

    在探究之前我们已知如下知识点

    • 函数内部的this总是在运行时决定指向
    • 直接调用的函数或自执行函数的内部this指向全局对象

    那么ES6的class例子的行为理应和其他例子保持一致,为什么会出现指向undefined的情况?那么一定是class内部有什么不同。

    我在搜索ES6 class的源码时发现这么一个仓库:里面有一个es6 class转换成普通函数书写的转码器。

    我们看到实际上class可以这样转义:

    // Classes
    class Person {
      constructor(firstName, lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
      }
    
      get name() {
        // Template strings
        return `${this.firstName} ${this.lastName}`;
      }
    
      toString() {
        return this.name;
      }
    }
    
    // Normal Function
    var $__Object$defineProperties = Object.defineProperties;
    
    var Person = function() {
      "use strict";
    
      function Person(firstName, lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
      }
    
      $__Object$defineProperties(Person.prototype, {
        name: {
          get: function() {
            // Template strings
            return "" + this.firstName + " " + this.lastName + "";
          },
    
          enumerable: true,
          configurable: true
        },
    
        toString: {
          value: function() {
            return this.name;
          },
    
          enumerable: false,
          writable: true
        }
      });
    
      return Person;
    }();
    

    那么我们的例子转义后的结果将是:

    var $__Object$defineProperties = Object.defineProperties;
    
    // instance method
    var T = function() {
      "use strict";
    
      function T() {}
    
      $__Object$defineProperties(T.prototype, {
        func: {
          value: function() {
            function f() {
              return this
            }
            console.log(f())
            return f
          },
    
          enumerable: false,
          writable: true
        }
      });
    
      return T;
    }();
    
    let obj = new T()
    obj.func()()
    
    // static method
    var T = function() {
      "use strict";
    
      function T() {}
    
      $__Object$defineProperties(T, {
        func: {
          value: function() {
            function f() {
              return this
            }
            console.log(f())
            return f
          },
    
          enumerable: false,
          writable: true
        }
      });
    
      return T;
    }();
    
    T.func()()
    

    实际上和我们上面普通function写法别无二致,唯一不同的就是这个"use strict"。首先正常在控制台执行两个转义后代码的例子,结果仍然是this指向undefined;而后我们尝试删掉"use strict"this确实又指向了window

    原来一切都是因为严格模式啊。

    关于严格模式的说明,大家可以参照阮老师Javascript 严格模式详解这篇文章,文章中提到的一点正解释了我们今天问题的现象。

    原来是严格模式

    最后我们顺便简单总结一下使用严格模式后产生的影响:

    • 全局变量必须显式声明
    • 禁止使用with语句
    • 创设eval作用域
    • 禁止this关键字指向全局对象
    • 禁止在函数内部遍历调用栈,限制arguments的使用
    • 禁止删除变量
    • 对象属性、函数参数重名报错
    • function函数必须声明在顶层
    • 新增保留字

    起源地下载网 » 原来是严格模式

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元