JavaScript严格模式

88 阅读4分钟

严格模式

  1. 给未声明的变量赋值,则会导致抛出 ReferenceError;

  2. 不能定义名为 eval 和 arguments 的变量,否则会导致语法错误;

  3. 八进制字面量在严格模式下是无效的,会导致 JavaScript 引擎抛出语法错误。ECMAScript 2015 或 ES6 中的八进制值通过前缀 0o 来表示;严格模式下,前缀 0 会被视为语法错误,如果要表示八进制值,应该使用前缀 0o;

  4. 严格模式不允许使用 with 语句,否则会抛出错误;

  5. 严格模式对函数也有一些限制:

    函数不能以 eval 或 arguments 作为名称;

    函数的参数不能叫 eval 或 arguments;

    两个命名参数不能拥有同一个名称。

    如果违反上述规则,则会导致语法错误,代码也不会执行。

暂时性死区

在解析代码时,JavaScript 引擎也会注意出现在块后面的 let 声明,只不过在此之前不能以任何方式来引用未声明的变量。在 let 声明之前的执行瞬间被称为“暂时性死区”(temporal dead zone),在此阶段引用任何后面才声明的变量都会抛出 ReferenceError。

优先使用const 、let次之

使用 const 声明可以让浏览器运行时强制保持变量不变,也可以让静态代码分析工具提前发现不 合法的赋值操作。因此,很多开发者认为应该优先使用 const 来声明变量,只在提前知道未来会有修改时,再使用 let。这样可以让开发者更有信心地推断某些变量的值永远不会变,同时也能迅速发现因意外赋值导致的非预期行为。

typeof 操作符

对一个值使用 typeof 操作符会返回下列字符串之一:

  • "undefined"表示值未定义;
  • "boolean"表示值为布尔值;
  • "string"表示值为字符串;
  • "number"表示值为数值;
  • "object"表示值为对象(而不是函数)或 null;
  • "function"表示值为函数;
  • "symbol"表示值为符号。

instanceof

image.png

按照定义,所有引用值都是 Object 的实例,因此通过 instanceof 操作符检测任何引用值和 Object 构造函数都会返回 true。类似地,如果用 instanceof 检测原始值,则始终会返回 false,因为原始值不是对象。

for-in 、 for-of

for-in 语句是一种严格的迭代语句,用于枚举对象中的非符号键属性,ECMAScript 中对象的属性是无序的,因此 for-in 语句不能保证返回对象属性的顺序,如果 for-in 循环要迭代的变量是 null 或 undefined,则不执行循环体

for-of 语句是一种严格的迭代语句,用于遍历可迭代对象的元素,for-of 循环会按照可迭代对象的 next()方法产生值的顺序迭代元素。

垃圾回收的 标记清理和引用计数

确定哪个变量不会再使用,然后释放它占用的内存。这个过程是周期性的,即垃圾回收程序每隔一定时间(或者说在代码执行过程中某个预定的收集时间)就会自动运行。

标记清理

JavaScript 最常用的垃圾回收策略是标记清理(mark-and-sweep)。标记过程的实现并不重要,关键是策略。

垃圾回收程序运行的时候,会标记内存中存储的所有变量(记住,标记方法有很多种)。然后,它 会将所有在上下文中的变量,以及被在上下文中的变量引用的变量的标记去掉。在此之后再被加上标记的变量就是待删除的了,原因是任何在上下文中的变量都访问不到它们了。随后垃圾回收程序做一次内存清理,销毁带标记的所有值并收回它们的内存。

引用计数

其思路是对每个值都记录它被引用的次数。声明变量并给它赋一个引用值时,这个值的引用数为 1。如果同一个值又被赋给另一个变量,那么引用数加 1。类似地,如果保存对该值引用的变量被其他值给覆盖了,那么引用数减 1。当一个值的引用数为 0 时,就说明没办法再访问到这个值了,因此可以安全地收回其内存了。垃圾回收程序下次运行的时候就会释放引用数为 0 的值的内存。

在某些浏览器中是有可能(但不推荐)主动触发垃圾回收的。在 IE 中,window.CollectGarbage()方法会立即触发垃圾回收。在 Opera 7 及更高版本中,调用 window. opera.collect()也会启动垃圾回收程序。

性能优化