• JS的严格模式


    ES5最早引入了严格模式的概念。通过严格模式,可以在函数内部选择进行较为严格的全局或局部的错误条件检测。可以提早知道代码中存在的错误,及时捕获一些可能呆滞编程错误的ECMAScript行为

    1.使用

    在需要使用严格模式的作用域顶部加上如下代码:

    "use strict"

    此时该作用域(或文件)中的JS代码都将处于严格模式下。

    如果没有控制页面中所有脚本的权力,建议只在需要测试的特定函数中开启严格模式

    2.严格模式下的限制

    (1)变量

    •  不允许意外创建全局变量
      • 如在非严格模式下,可以像下面这样创建全局变量:
        •   msg = "hello"
      • 严格模式下:
        • "use strict"
          msg = "hello"    // Uncaught ReferenceError: msg is not defined
    • 另外:严格模式下对变量名也有限制。特别地,不能使用 implements、interface、let、package、private、protected、public、static 和 yield 作为变量名。这些都是保留字,将来的 ECMAScript版本中可能会用到它们。在严格模式下,用以上标识符作为变量名会导致语法错误。

    (2)对象

    • 严格模式下操作对象比在非严格模式下更容易导致错误,一般来说,非严格模式下会静默失败的情况,严格模式下就会抛出错误,如:
      • 为只读属性赋值会抛出TypeError(writeable = true)
        • 非严格模式下默认失败:
          • 1     let obj = { name: "张三" }
            2     Object.defineProperty(obj, "name", {
            3         writable: false
            4     })
            5 
            6     obj.name = "李四"
            7 
            8     console.log(obj.name);  // 张三
        • 严格模式下会抛出错误:
          • 1     "use strict"
            2     let obj = { name: "张三" }
            3     Object.defineProperty(obj, "name", {
            4         writable: false
            5     })
            6 
            7     obj.name = "李四"
            8 
            9     console.log(obj.name);  // Uncaught TypeError: Cannot assign to read only property 'name' of object '#<Object>'
      • 对不可配置的属性使用delete操作符会抛出TypeError(configurable = false)
        • 非严格模式:
          • 1     let obj = { name: "张三" }
            2     Object.defineProperty(obj, "name", {
            3         configurable: false
            4     })
            5 
            6     delete obj.name
            7 
            8     console.log(obj);   // {name: "张三"}
        • 严格模式:
          • 1     "use strict"
            2     let obj = { name: "张三" }
            3     Object.defineProperty(obj, "name", {
            4         configurable: false
            5     })
            6 
            7     delete obj.name // Uncaught TypeError: Cannot delete property 'name' of #<Object>
            8 
            9     console.log(obj);
      • 对不可扩展的对象添加属性会抛出TypeError(Object.preventExtensions()、Object.seal()、Object.freeze())
        • 以上保护对象的三个方法从左到右,保护级别依次提升。具体区别见此
        • 非严格模式:
          • 1     let obj = { name: "张三" }
            2 
            3     Object.preventExtensions(obj)
            4     obj.age = 12
            5 
            6     console.log(obj);   // {name: "张三"}
        • 严格模式:
          • 1     "use strict"
            2     let obj = { name: "张三" }
            3 
            4     Object.preventExtensions(obj)
            5     obj.age = 12    // Uncaught TypeError: Cannot add property age, object is not extensible
            6 
            7     console.log(obj);  

    (3)函数

    • 严格模式要求命名函数的参数必须唯一:
      • 非严格模式:没有错误,只能访问第二个参数
        • 1     function sum (num,num){
          2         console.log(num);
          3     }
          4 
          5     sum(1,2)    // 2
      • 严格模式:
        • 1     "use strict"
          2     function sum (num,num){   // Uncaught SyntaxError: Duplicate parameter name not allowed in this context
          3         console.log(num);
          4     }
          5 
          6     sum(1,2) 
    • 严格模式下,禁用了argument.callee和argument.caller
      • 非严格模式:
        • 1     function factorial(num){
          2         if(num <=1){
          3             return 1
          4         }else{
          5             return num + arguments.callee(num-1)
          6         }
          7     }
          8 
          9     console.log(factorial(100));    // 5050
      • 严格模式:
        • 1     function factorial(num){
          2         if(num <=1){
          3             return 1
          4         }else{
          5             return num + arguments.callee(num-1)
          6         }
          7     }   // Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
          8 
          9     console.log(factorial(100)); 
    •  还有一个限制:就是只能在脚本的顶级和在函数的内部声明函数。也就是说,在if语句中声明函数会导致语法错误

    (4)eval

    • eval在包含上下文中不再创建变量或者函数
      • 非严格模式下,fn()中的eval代码执行后会在函数fn的作用域中创建一个局部变量x
        • 1     function fn(){
          2         eval("var x = 1")
          3         alert(x)
          4     }
          5     fn()  // 弹框并出现1
      • 严格模式下:
        • 1     "use strict"
          2     function fn(){
          3         eval("var x = 1")
          4         alert(x)
          5     }  // Uncaught ReferenceError: x is not defined
          6     fn()

    (5)eval和arguments

    • 禁止把eval和arguments作为变量引用
    • 禁止重写eval和arguments:
      • 使用var声明
      • 赋予另外一个值
      • 尝试修改包含的值
      • 作为函数名
      • 用作命名的函数参数
      • 在try-catch语句中用作例外名

    (6)this

    严格模式下的函数中的this将指向undefined(在非严格模式下指向window)

  • 相关阅读:
    操作系统
    网络通信协议(互联网协议)
    返回Json数据 结构封装R
    开放平台,开发者的时代到来?
    seo的html代码优化
    推广网站要做的事情
    Java对象转xml字符串
    也来一段Mootools的图片切换代码
    new关键字用法
    关于CTS、CLS、CLR
  • 原文地址:https://www.cnblogs.com/codexlx/p/14301347.html
Copyright © 2020-2023  润新知