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

    1.什么是严格模式?

    js运行有两种模式:一种是普通模式;一种是严格模式。

    严格模式是ES5添加的,是比普通模式多一部分的js规则。如果在ES5之前js解析引擎,会忽略严格模式。

    js一般默认是普通模式,ES6的模块和Class类默认是严格模式。

    2. 严格模式的使用场景

    严格模式的触发是使用: "use strict"

    有两种使用场合:一种是脚本范围;一种是函数范围

    1.脚本范围

    1.在html文件中,可以在<script> 标签内的顶部直接使用"use strict";

    "use strict"上面不能有可执行代码,否则失效;但是上面可以是注释内容或者空行。

    ❗️一个脚本内抛出异常,后面的代码不再执行;但是其他的脚本可以。如下:

    <script>
      console.log(1); 
      "use strict"; //上面有代码,自动失效
      a=6;
    </script>
    <script>
    
      /* 这是个脚本注释,并且上面空了一行*/
      "use strict"; // 严格模式;下面是声明时报错
      b=6; // Uncaught ReferenceError: b is not defined
    </script>
    <script>
      "use strict"; // 严格模式
      c=6; // Uncaught ReferenceError: c is not defined
    </script>

    2.在一个脚本文件中,在顶部声明"use strict";顶部有注释或者空行(空;行不可以)也可以。

    //--- es5.js
    //
    顶部的注释;并且有一个空行,整个文件都是严格模式 "use strict"; function test(a,a) { // Uncaught SyntaxError: Duplicate parameter name not allowed in this context // 严格模式不允许参数重复;声明时报错 }

     上面的写法有隐患,如果项目内部需要脚本合并,如严格模式A.js和普通模式B.js,如果A在前,那么

    B也会被解释成严格模式;如果B在前,那么A的严格模式会失效。

    所以,如果是单独的文件,可以使用立即执行函数包裹以下,这样可以避免脚本合并的BUG。

    // 这个是A.js的代码;代码效果和上面的相同,但是可以保证代码的独立
    (function() {
       "use strict"; // 函数内部严格模式
        function test(a,a) { // Uncaught SyntaxError: Duplicate parameter name not allowed in this context
        }
    })();

    2.函数范围

    在一个函数内顶部使用"use strict";那么在一个函数内是严格模式。

        function test() {
          // 函数的注释
          "use strict";
          t = 7;
        }
        // 声明时不报错;执行时报错
        test();  // Uncaught ReferenceError: t is not defined

    3. 浏览器控制台范围

    开发者最方便的调试工具是console控制台;默认是普通模式,可以手动设置严格模式;

     3. 严格模式的内容

    1. 显式报错

    将普通模式中默默失败的错误,改为显式报错。

    • 1. 只读属性赋值报错;删除不可配置属性报错

    原先只读属性赋值或者删除不可配置属性,默默失败,不会抛出异常;严格模式下,会抛出异常。

    "use strict";
    class A {
    }
    class B{}
    // 类的prototype属性的writable,configurable,enumerable都是false
    A.prototype = new B(); // Uncaught TypeError: Cannot assign to read only property 'prototype' of function 'class A {}'
    delete A.prototype; // Uncaught TypeError: Cannot delete property 'prototype' of class A {}'
    • 2.只设置了取值器的对象不可写
    "use strict";
    var a = {
        get prop() {
            return 1;
        }
    }
    a.prop = 5; //Uncaught TypeError: Cannot set property prop of #<Object> which has only a getter
    • 3.禁止扩展的对象不可扩展(不能添加新属性)
    "use strict";
    var a = {};
    Object.preventExtensions(a);
    a.x = 0; //Uncaught TypeError: Cannot add property x, object is not extensible
    • 4.eval,arguments不可用作标识名

    javascript中的保留字在严格模式下都会报错;实际开发中注意变量名不要是保留关键字。

    非严格模式下,不会报错。

    "use strict";
    var eval = 5; //Uncaught SyntaxError: Unexpected eval or arguments in strict mode
    function test(arguments) { //Uncaught SyntaxError: Unexpected eval or arguments in strict mode
    }
    • 5.函数参数名不能重复
    • 6. 禁止使用0前缀表示八进制数。

    ES6中也有规定,八进制数应该使用“0o”表示。

    "use strict";
    var a = 0o10;
    console.log(a); // 8
    var b = 010; // Uncaught SyntaxError: Octal literals are not allowed in strict mode.

    2. 加强安全

    从语法书写上避免错误的产生。

    • 1. 严格模式下,不允许this指向window

    js引擎将其指向undefined。这个很好的解释了React类组件中方法必须绑定this,

    否则默认this是undefined。

    这时fn.call()/fn.call(null)/fn.call(undefined)不再默认绑定window。绑定的就是括号中的内容。

    • 2. 不允许未声明的变量出现

    即变量必须使用var, let等声明,否则报错。原来未声明的变量会默认成为全局变量。

    "use strict";
    a = 5;  // Uncaught ReferenceError
    • 3.禁止使用fn.caller/fn.arguments

    首先fn.caller不是标准语法;生产环境禁止使用;fn.arguments已被废弃

    但是某些情况下也会使用。

    fn.caller是返回fn的调用栈,即触发该函数的函数;

    如果在全局环境下调用,fn.caller()是null。

    // 这是非严格模式;只是为了解释caller的概念;严格模式下报错
    function test() {
        a();
        console.log(test.caller);//null
    }
    function a() {
        console.log(a.caller); // function test(){a();}
    }
    test();

    fn.arguments其实就是参数对象。可以在函数中直接使用arguments对象。

    • 4.禁止使用arguments.callee/arguments.caller

    这两个属性已经废弃。普通模式下使用,代码无效,不报错;严格模式下报错。

    原来arguments.callee表示当前函数;arguments.caller和fn.caller一样。

    • 5.不可删除声明的普通变量

    普通模式下可以删除,并且可以删除成功。

    "use strict";
    let a = 6;
    delete a; //Uncaught SyntaxError: Delete of an unqualified identifier in strict mode.
    • 6.严格模式下原始类型的值不能赋属性

    普通模式下不报错,会自动将原值值转为包装对象。

    "use strict";
    (1).prop = 9; // Uncaught TypeError: Cannot create property 'prop' on number '1'

    3. 禁止出现动态作用域

    普通模式下,eval()和with()会在执行时动态生成作用域。

    • 1. 禁止使用with语句

    在严格模式下,使用with语句会报错。其实普通模式下,也不要使用with语句。

    "use strict";
    var obj ={};
    with(obj) { //Uncaught SyntaxError: Strict mode code may not include a with statement
        a = 5;
    }
    • 2.创建eval作用域

    严格模式下,eval()会创建一个eval函数内部的作用域。

    普通模式下, eval内部代码所在的作用域是函数所在的作用域。

    // 普通模式下
    function test() {
        var x = 5;
        eval("var x = 6"); //相当于直接var x= 6;
        console.log(x); // 6
    }
    test();
    //  严格模式下
    "use strict"; // 1.第一种声明位置
    function test() {
        // "use strict"; // 2.也可以在这里声明
        var x = 5;
        eval("var x = 6"); // 只在eval内部有效
        // 3. 还可以如下声明
        // eval('"use strict"; var x= 6');
        console.log(x); // 5
    }
    test();
    • 3.arguments对象不再随参数改变而改变
    // 普通模式
    function test(a) {
       a = 2;
       return [a, arguments[0]];
    }
    console.log(test(1));  // [2, 2]
    // 严格模式
    "use strict";
    function test(a) {
       a = 2;
       return [a, arguments[0]]; 
    }
    console.log(test(1)); // [2, 1]

    4.向未来版本过渡

  • 相关阅读:
    sqlserver where in 在 mysql
    C# MVC 获得程序运行路径 .net core
    matplotlib之scatter自动绘制散点
    matplotlib之scatter绘制散点
    可视化数据matplotlib之安装与简单折线图
    selenium之批量执行测试用例
    selenium之使用unittest测试框架
    python之使用smtplib模块发送邮件
    python之time模块:获取当前时间
    一个IT人士的个人经历,给迷失方向的朋友
  • 原文地址:https://www.cnblogs.com/lyraLee/p/11710022.html
Copyright © 2011-2022 走看看