zoukankan      html  css  js  c++  java
  • JavaScript的严格模式

    js除了在普通的常规模式,ECMAscript 5添加了第二种运行模式:"严格模式"(strict mode)。严格模式支持IE9+ Chrome FireFox 等主流浏览器。

    定义严格模式

    使用'use strict'规定严格模式,'use strict'必须写在代码块顶部,可以定义在整个js文件顶部(作用域就是整个js文件),也可以定义在某个function中第一行(作用域仅是function函数)。

    'use strict'
    document.write('这是严格模式');

    如上代码,即整个js文件定义为严格模式

            y = 2;
            document.write('这是普通模式' + y); 
            fun();
            function fun(){
                'use strict'
                document.write('这是严格模式');
            }

    如上代码,既仅fun()函数定义为严格模式

            y = 2;
            document.write(y);
            'use strict'            //如果'use strict'被定义在中间,严格模式不生效
            x = 1;
            document.write(x); 

    定义在代码中间的'use strict'被视为字符串处理

    (严格地说,只要前面不是产生实际运行结果的语句,"use strict"可以不在第一行,比如直接跟在一个空的分号后面。)

    严格模式作用

     //消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;
     //消除代码运行的一些不安全之处,保证代码运行的安全;
     //提高编译器效率,增加运行速度;
     //为未来新版本的Javascript做好铺垫。

    严格模式与普通模式的区别

    1. 在正常模式中,如果一个变量没有声明就赋值,默认是全局变量。严格模式禁止这种用法,全局变量必须显式声明。严格模式下,变量都必须先用var命令声明,然后再使用
              "use strict";
            v = 1; // 报错,v未声明
            for(i = 0; i < 2; i++) { // 报错,i未声明
            }
    2. 禁止使用with语句,在严格模式下with直接被视为语法错误。
              "use strict";
            var v = 1;
            with (o){ // 语法错误 
              v = 2;
            }
    3. eval有独立作用域。
              "use strict";
            var x = 2;
            console.log(eval("var x = 5; x"));     // 输出5
            console.log(x);     // 输出2

      普通模式:JS有两种变量作用域:全局作用域和函数作用域

      严格模式:除了全局作用域和函数作用域外,创设了第三种作用域:eval作用域。所以eval在严格模式下独立为一个作用域。

      正常模式:eval语句的作用域,取决于它处于全局作用域,还是处于函数作用域。

      严格模式:eval语句本身就是一个作用域,不再能够生成全局变量了,它所生成的变量只能用于eval内部。

    4. 禁止this关键字指向全局对象。
      //普通模式下,this默认指向全局对象      
              fun();
              function fun(){
                  console.log(this.a);    //输出undefined
              }
      //严格模式下,禁止this指向全局对象,这样this的指向就更严谨。弥补了js天生的"太随意"
             "use strict";
           fun();
              function fun(){
                  console.log(this.a);    //直接报错。
              }
    5. 禁止在函数内部遍历调用栈。
           function f1(){
          "use strict";
          f1.caller;              // 报错
          f1.arguments;     // 报错
        }
        f1();    
    6. 严格模式下的显式报错。
      1. 普通模式下,对一个对象的只读属性进行赋值,不会报错,只是默默地失败。严格模式下,将报错。
          "use strict";
          var o = {};
          Object.defineProperty(o, "v", { value: 1, writable: false });
          o.v = 2; // 报错
      2. 严格模式下,对一个使用getter方法读取的属性进行赋值,会报错。
          "use strict";
          var o = {
            get v() { return 1; }
          };
          o.v = 2; // 报错

      总之,在严格模式下,很多错误都会显示报错,不在忽略或直接处理为undefined。这样大大方便了bug的效率。

    7. 重名错误。

      在严格模式下增加了重名检查,函数内属性重名不再是后面覆盖前面,而是直接报错。

          "use strict";
        var o = {
          p: 1,
          p: 2
        };     // 报错

      而且严格模式下,函数的参数也不能重名。

          "use strict";
        function f(a, a, b) { // 报错
          return ;
        }
    8. 函数必须声明在顶层

      将来Javascript的新版本会引入"块级作用域"。为了与新版本接轨,严格模式只允许在全局作用域或函数作用域的顶层声明函数。也就是说,不允许在非函数的代码块内声明函数。

        "use strict";
        if (true) {
          function f() { } // 语法错误
        }
        for (var i = 0; i < 5; i++) {
          function f2() { } // 语法错误
        }
    9. 新增保留字

      为了向将来Javascript的新版本过渡,严格模式新增了一些保留字:implements, interface, let, package, private, protected, public, static, yield。所以使用这些保留字作为变量名会报错。

        "use strict";
            var let;         //语法错误
            function package(protected) { // 语法错误
          "use strict";
          var implements; // 语法错误
        }    

    本文参照http://www.ruanyifeng.com/blog/2013/01/javascript_strict_mode.html,详细了解。

  • 相关阅读:
    completable 用法
    spring 纯注解方式 与AOP
    springIOC原理加载过程
    多线程手写Future模式
    springMVC 实现redis分布式锁
    java线程池学习
    本地跑 spark ui 报错
    九度oj 题目1452:搬寝室
    九度oj 题目1456:胜利大逃亡
    九度oj 题目1455:珍惜现在,感恩生活
  • 原文地址:https://www.cnblogs.com/MirageFox/p/5725989.html
Copyright © 2011-2022 走看看