__x__(81)1017第十六天__ JavaScript 严格模式

严格模式

除了正常的运行模式,JavaScript 还有第二种运行模式:严格模式(strict mode)。顾名思义,这种模式采用更加严格的 JavaScript 语法

同样的代码,在正常模式和严格模式中,可能会有不一样的运行结果。

一些在正常模式下可以运行的语句,在严格模式下将不能运行。

  • 设计目的

    • 早期的 JavaScript 语言有很多设计不合理的地方,但是为了兼容以前的代码,又不能改变老的语法,
    • 只能不断添加新的语法,引导程序员使用新语法
    • 严格模式是从 ES5 进入标准的,主要目的有以下几个。
      • 明确禁止一些不合理、不严谨的语法,减少 JavaScript 语言的一些怪异行为
      • 增加更多报错的场合,消除代码运行的一些不安全之处,保证代码运行的安全
      • 提高编译器效率,增加运行速度
      • 为未来新版本的 JavaScript 语法做好铺垫
  • 启用方法

进入严格模式的标志,是一行字符串 use strict;

  • ‘use strict‘;
    • 在整个脚本文件 启用

      • 放在脚本文件的第一行,整个脚本都将以严格模式运行。
      • <script>
            ‘use strict‘;
            console.log(‘这是严格模式‘);
        </script>
        
        <script>
            console.log(‘这是正常模式‘);
        </script>
    • 只在单个函数中 启用
      • use strict; 放在函数体的第一行,则整个函数以严格模式运行
    • 有时,需要把不同的脚本合并在一个文件里面。

      • 如果一个脚本是严格模式,另一个脚本不是,它们的合并就可能出错。
        • 严格模式的脚本在前,则合并后的脚本都是严格模式
        • 如果正常模式的脚本在前,则合并后的脚本都是正常模式
      • 这时可以考虑把整个脚本文件放在一个立即执行的匿名函数之中

        (function () {
            ‘use strict‘;
            // some code here
        })();
  • 显示报错

严格模式使得 JavaScript 的语法变得更严格,更多的操作会显式报错

其中有些操作,在正常模式下只会默默地失败,不会报错

    • 只读属性不可写

      • 严格模式下,设置字符串的 length 属性,会报错    // TypeError: Cannot assign to read only property ‘length‘ of string ‘abc‘
      • 删除不可配置(non-configurable)属性都会报错
    • 禁止扩展的对象不可扩展

      • 严格模式下,对禁止扩展的对象添加新属性,会报错

        ‘use strict‘;
        var obj = {};
        Object.preventExtensions(obj);
        
        obj.v = 1;    // Uncaught TypeError: Cannot add property v, object is not extensible
    • 严格模式下,对一个只有取值器(getter)、没有存值器(setter)的属性赋值,会报错

 

    • eval、arguments 不可用作标识名

 

    • 函数不能有重名的参数

 

    • 禁止八进制的前缀0表示法
  • 增强的安全措施

    • 全局变量必须显式声明
    • 禁止 this 关键字指向全局对象
    • 函数禁止使用 fn.callee    fn.caller
    • 禁止使用 arguments.callee、arguments.caller

      • 只有对象的属性,且属性的描述对象的 configurable 属性设置为 true,才能被 delete 命令删除
    • 禁止删除window 的变量
  • 静态绑定
        • JavaScript 语言的一个特点,就是允许 “动态绑定”,
        • 即某些属性和方法到底属于哪一个对象,不是在编译时确定的,而是在运行时(runtime)确定的。
        • 某些情况下,只允许静态绑定。也就是说,属性和方法到底归属哪个对象,必须在编译阶段就确定。
        • 这样做有利于编译效率的提高,也使得代码更容易阅读,更少出现意外。
    • 禁止使用 with 语句

      • 因为with语句无法在编译时就确定,某个属性到底归属哪个对象,从而影响了编译效果
    • 创设 eval 作用域

      • 正常模式下,JavaScript 语言有两种变量作用域(scope):全局作用域和函数作用域
      • 严格模式创设了第三种作用域:eval作用域
      • eval 所生成的变量只能用于 eval 内部
        • (function () {
              ‘use strict‘;
              var x = 2;
              console.log(eval(‘var x = 5; x‘))    // 5
              console.log(x)    // 2
          })()
      • 如果希望 eval 语句也使用严格模式,有两种方式
        • // 方式一
          function f1(str){
              ‘use strict‘;
              return eval(str);
          }
          
          f1(‘undeclared_variable = 1‘);    // 报错
          
          // 方式二
          function f2(str){
              return eval(str);
          }
          
          f2(‘"use strict";undeclared_variable = 1‘)     // 报错
      • arguments 不再追踪参数的变化 
        • 变量arguments代表函数的参数。严格模式下,函数内部改变参数与arguments的联系被切断了,两者不再存在联动关系
    • 非函数代码块不得声明函数

      • 只允许在全局作用域或函数作用域声明函数
    • 保留字

      • implements、interface、let、package、private、protected、public、static、yield等

原文地址:https://www.cnblogs.com/tianxiaxuange/p/9806763.html

时间: 2024-09-29 17:03:19

__x__(81)1017第十六天__ JavaScript 严格模式的相关文章

__x__(64)0925第十天__ JavaScript 对象的 toString() 方法改变输出

JavaScript 对象的 toString() 方法改变输出 在平常,我们 console.log(对象);    // 会打印 [Object Object] 但是我们想要更详细的输出,此时,我们可以重写 对象.toString() 方法 Person.toString = function(){ return "Person ["+this.name+" , "+this.gender+","+this.age+"]"

__x__(59)0925第十天__ JavaScript 其他知识

对象的属性值 如果要使用特殊的属性名,需 对象["属性名"] = 属性值       // 存 对象["属性名"]       // 取 obj["123"] = 456; var n = "123"; // 可以传一个变量到 [] ,来取变量对应在 Object 中的属性值 console.log(obj[n]); 对象的属性值可以是任意数据类型,包括对象和函数. 使用 in 运算符来检查一个对象是否含有某属性 consol

__x__(60)0925第十天__ JavaScript 函数对象

1. 创建一个函数对象 var myFunc = new Function(); // typeof myFunc 将会打印 function 将要封装的代码以字符串的方式传递给构造函数 var aFunc = new Function("console.log('Hello!');"); console.log(aFunc); // 打印: " function anonymous(){ console.log("Hello!"); } " 使

__x__(63)0925第十天__ JavaScript 函数 上下文对象 原型对象

解析器在每次调用函数时,都会传递两个隐含参数: this    上下文对象 根据函数调用方式的不同,this 指向不同的对象 当作为普通函数调用时,this 指向全局对象 window 当作为对象的方法被调用时,this 指向调用该方法的对象 当作为构造函数调用时,this 指向创建的新对象 构造函数 出现的原因:由于目前为止,我们的对象都是用 new Object() 创建的,所以都是 Object 类的对象,不好区分...最好有个 Person 类,Animal 类 new Person()

__x__(54)0918第七天__ JavaScript

JavaScript 运算符,也叫操作符 对一个或者多个值进行运算,都是会返回结果的. 比如: typeof    返回一个值的类型,返回值类型是字符串. 隐式类型转换: 任意值 = 任意值 + "";    // 就能转换成字符串 任意值 = 任意值 - 0;    // 就能转换成Number 任意值 = +任意值;    // 就能转换成 Number,更简洁 任意值 = !!任意值;    // 即可将 任意值 转换成布尔类型的值 算术运算符, 不会对等号右边的值产生影响: 对

python入门第十六天__列表生成式

列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式. 举个例子,要生成list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]可以用list(range(1, 11)): >>> list(range(1, 11)) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 但如果要生成[1x1, 2x2, 3x3, ..., 10x10]怎么做?方法一是循环: >>> L = []

__x__(75)1012第十三天__ JavaScript 包装对象

包装对象 所谓“包装对象”,就是分别与数值.字符串.布尔值相对应的Number.String.Boolean三个原生对象 这三个原生对象可以把原始类型的值变成(包装成)对象 var v1 = new Number(123); var v2 = new String('abc'); var v3 = new Boolean(true); typeof v1 // "object" typeof v2 // "object" typeof v3 // "obj

(82)Wangdao.com第十六天1017__ JavaScript 异步操作

异步操作 单线程模型 指的是,JavaScript 只在一个线程上运行 也就是说,JavaScript 同时只能执行一个任务,其他任务都必须在后面排队等待 注意,JavaScript 只在一个线程上运行,不代表 JavaScript 引擎只有一个线程. 事实上,JavaScript 引擎有多个线程,单个脚本只能在一个线程上运行(称为主线程),其他线程都是在后台配合 JavaScript 之所以采用单线程,而不是多线程,跟历史有关系. JavaScript 从诞生起就是单线程,原因是不想让浏览器变

__x__(53)0918第七天__ JavaScript 强制类型转换

其他进制的数字 二进制    以 0b 开头的 Number 八进制    以 0 开头的 Number 十六进制    以 0x 开头的 Number 注意:无论是多少进制的数字,输出都是十进制 强制类型转换 主要指的是将 变量类型 转换为String,Number,Boolean类型. 1. 转换为字符串 String 通过调用 String.toString() 方法 : Null .Undefined 没有 .toString() 方法,意味着不能用此方法转换 var a = 123;