严格模式

发布于 2020-07-02  109 次阅读


  • 有时候,相同的代码,严格模式可以比非严格模式下运行的更快。严格模式下修复了JavaScript引擎难以执行的缺陷
  • 严格模式下不能再意外的创建全局变量 所以这样子的情况将会报错
  •   "use strict";
      a=1;  //ReferenceError: a is not defined
  • 严格模式下,一些在非严格模式下的[错误而不报错的错误操作]将会抛出错误
  •   "use strict";
      NaN=1 //TypeError: Cannot assign to read only property 'NaN' of object
            //非严格模式下,不会报错
      delete Object.prototype; //TypeError: Cannot delete property 'prototype' of function Object()
            //非严格模式下,不会报错
  • 在对象内,已经被定义了的属性,不允许被再次定义。但是在ES6中使用,貌似不会再报错了。
  •   "use strict";
      var obj={
          p:1;
          p:2
      }; //报错
  • 函数的形参名不允许重,而在非严格模式下,只会把最后一个重复的形参值覆盖前面的,而不会报错,同时可以使用argument伪数组进行访问
  •   "use strict";
      function fun(a,a){
          console.log(a); //  SyntaxError: Duplicate parameter name not allowed in this context
      }
      fun(1,2);
      function fun(a,a){
          console.log(a);
      }
      fun(1,2); // 2
  • 严格模式下不允许使用八进制数字语法,0123这样子都不被允许,但是0o123可以在严格模式下使用(ES6),二进制形式也被允许使用0x1010
  •   "use strict";
      let a=0123; // SyntaxError: Octal literals are not allowed in strict mode.
      let b=0o123; // 不报错
      let c=0x1010; // 不报错
  • 严格模式下基本数据类型不允许设置属性,在非严格模式下,虽然是无用的操作,但是不报错
  •   "use strict";
      true.p=1; // TypeError: Cannot create property 'name' on boolean 'true'
  • 严格模式下禁止使用with
  • 严格模式下,eval()函数内创建新的变量,不会再引入到函数所在的作用域内。
  •   "use strict";
      eval('var a=1;');
      console.log(a); // ReferenceError: a is not defined
      eval('"use strict";var a=1;');
      console.log(a); // ReferenceError: a is not defined
      eval('var a=1;');
      console.log(a); // 1
  • 严格模式下,delete删除不能删除的东西,比如变量,将会报错
  •   "use strict";
      var a=1;
      delete a; // SyntaxError: Delete of an unqualified identifier in strict mode.
  • 严格模式下,evalarguments不允许被绑定和赋值
  • 严格模式下,函数中实参的值与arguments伪数组对应的值,不会随着另外一个的变化而变化
  •   "use strict";
      function fun(a,b){
          a=0;
          console.log(a,b); // 0 2
          console.log(arguments[0],arguments[1]); // 1 2
      }
      fun(1,2);
      "use strict";
      function fun(a,b){
          arguments[0]=0;
          console.log(a,b); // 1 2
          console.log(arguments[0],arguments[1]); // 0 2
      }
      fun(1,2);
      function fun(a,b){
          arguments[0]=0;
          console.log(a,b); // 0 2
          console.log(arguments[0],arguments[1]); // 0 2
      }
      fun(1,2);
  • 在严格模式下,函数内的arguments对象的callee属性不被允许使用,删除,赋值
  • 严格模式下,this发生了改变。没有指定this的话,它的值就是undefined(针对全局window),并且不再支持自动将this转换为对象的功能
  •   "use strict";
      function fun(a){
          console.log(this);
      }
      fun.call(true) // true
      "use strict";
      function fun(a){
          console.log(this);
      }
      fun() // undefined
      function fun(a){
          console.log(this);
      }
      fun.call(true) // Boolean对象
      function fun(a){
          console.log(this);
      }
      fun() // window对象

    并且这还会导致一个问题

      function Student(){
          this.name="jpc";
          this.age=19;
      }
      let stu=Student(); // TypeError: Cannot set property 'name' of undefined
      /*
      当我们启用了严格模式,原本是想要通过构造函数构造严格Student实例,忘了new。
      由于是在严格模式下,所以this的值是undefiend,所以报错了。
      而在非严格模式的情况下,此时window全局下会都出一个window.name和window.age属性
      */
  • 严格模式下,一个名为fun的函数,fun.caller fun.arguments(不是arguments)和arguments.caller都不能被访问,赋值和删除。
  • 严格模式下,ES5为以后保留了一部分关键字
  • 严格模式禁止了不在脚本或者函数层面上的函数声明【不太清除这一条,我测试没有报错】
  • 函数内使用了严格模式,那么参数默认值、解构赋值和rest参数都不能设置了
  • 这里需要注意的是,是在函数内使用了严格模式,即函数外作用域(或全局)设置了严格模式,是不受到影响的

      //设置参数默认值的报错
      function fun(x=0){
          "use strict";
          console.log(x) //报错
      }
      fun(1);
      //设置解构赋值的报错
      function fun({x}){
          "use strict";
          console.log(x) //报错
      }
      fun({x:1});
      //设置rest参数的报错
      function fun(...x){
          "use strict";
          console.log(x) //报错
      }
      fun(0,1,2,3);
      //不在函数内使用严格模式,无报错,正常运行
      "use strict";
      function fun(x=0){
          console.log(x) //1
      }
      fun(1);
      function fun({x}){
          console.log(x) //1
      }
      fun({x:1});
      function fun(...x){
          console.log(x) //[0,1,2,3]
      }
      fun(0,1,2,3);

    参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Strict_mode


    一个人只有亲眼看到自己伤疤的时候才知道什么是痛,什么是对与错。