不推荐和废弃的特性

本页面列出了 JavaScript 中已弃用(即仍可用但计划移除)和已废弃(即不再可用)的特性。

已弃用的功能

这些已废弃的特性仍然可以使用,但应谨慎使用,因为并非每个 JavaScript 引擎都要求实现它们。您应努力从代码中移除它们的使用。

其中一些已废弃的特性列在 ECMAScript 规范的附录 B 部分。此部分被描述为“规范可选”——即,Web 浏览器宿主必须实现这些特性,而非 Web 宿主则可能不实现。这些特性可能很稳定,因为移除它们将导致向后兼容性问题并破坏旧版网站。(JavaScript 的设计目标是“不要破坏网络”。)尽管如此,它们并非跨平台可移植,并且可能不被所有分析工具支持,因此建议您不要使用它们,正如附录 B 的引言所述:

…… 本附录中指定的所有语言特性和行为都具有一个或多个不受欢迎的特征,如果不存在历史使用情况,它们将被从本规范中移除。……

…… 程序员在编写新的 ECMAScript 代码时,不应使用或假设这些特性和行为的存在。……

其他一些特性,尽管在主规范主体中,也被标记为规范可选,不应依赖。

HTML 注释

JavaScript 源代码,如果被解析为脚本,允许使用类似 HTML 的注释,就好像脚本是 <script> 标签的一部分一样。

以下代码在 Web 浏览器中(或使用 V8 引擎的 Node.js)运行时是有效的 JavaScript:

js
<!-- comment
console.log("a"); <!-- another comment
console.log("b");
--> More comment
// Logs "a" and "b"

<!----> 都像 // 一样,即作为行注释的开头。--> 仅在行首有效(为了避免与后缀递减运算符后跟大于运算符的歧义),而 <!-- 可以出现在行中的任何位置。

RegExp

以下属性已弃用。这不影响它们在替换字符串中的使用。

$1–$9

任何带括号的子字符串匹配项。

input, $_

与正则表达式匹配的字符串。

lastMatch, $&

最后匹配的子字符串。

lastParen, $+

最后带括号的子字符串匹配项(如果有)。

leftContext, $`

最近匹配项之前的子字符串。

rightContext, $'

最近匹配项之后的子字符串。

警告:避免使用这些静态属性,因为它们在与外部代码交互时可能导致问题

compile() 方法已弃用。请改用新的 RegExp 实例。

以下正则表达式语法已弃用,并且仅在非 Unicode 模式下可用。在 Unicode 感知模式下,它们都是语法错误:

  • 先行断言可以带量词
  • 不引用现有捕获组的反向引用将成为旧版八进制转义序列
  • 字符类中,如果一个边界是字符类,则字符范围中的 - 会成为字面字符。
  • 未识别的转义序列将成为“标识转义”
  • 字符类中,形式为 \cX(其中 X 是数字或 _)的转义序列的解码方式与ASCII字母的解码方式相同:\c0\cP 模 32 的结果相同。此外,如果 \cX 的形式在任何地方出现,而 X 不是可识别的字符之一,则反斜杠将被视为字面字符。
  • 在不包含任何命名捕获组的正则表达式中,序列 \k 被视为标识转义。
  • 语法字符 ]{} 可以字面出现,而无需转义,如果它们不能被解释为字符类或量词分隔符的结尾。

Function

  • 函数的 caller 属性和 arguments.callee 属性已弃用,并且在严格模式下不可用。
  • 您应该在函数闭包内部使用 arguments 对象,而不是将 arguments 作为函数的属性访问。

Object

String

Date

转义序列

语句

with 语句已弃用,并且在严格模式下不可用。

for...in 循环头部中 var 声明的初始化器已弃用,并且在严格模式下会产生语法错误。初始化表达式会被评估并赋值给变量,但该值会在循环的第一次迭代时立即被重新赋值。

通常,try...catch 语句的 catch 块不能包含与 catch() 中绑定的变量同名的任何变量声明。一个扩展语法允许 catch 块包含一个与 catch 绑定标识符同名的 var 声明变量,但前提是 catch 绑定是一个简单的标识符,而不是一个解构模式。然而,这个变量的初始化和赋值只会作用于 catch 绑定的标识符,而不是上层作用域变量,并且行为可能令人困惑。

js
var a = 2;
try {
  throw new Error();
} catch (a) {
  var a = 1; // This 1 is assigned to the caught `a`, not the outer `a`.
}
console.log(a); // 2

try {
  throw new Error();
  // Note: identifier changed to `err` to avoid conflict with
  // the inner declaration of `a`.
} catch (err) {
  var a = 1; // This 1 is assigned to the upper-scope `a`.
}
console.log(a); // 1

这在规范的附录 B 中列出,因此可能不会在所有地方实现。避免 catch 绑定标识符与 catch 块中声明的变量之间存在任何名称冲突。

已废弃的特性

这些已废弃的特性已从 JavaScript 中完全移除,并且自所示 JavaScript 版本起不再可用。

RegExp

以下现在是 RegExp 实例的属性,不再是 RegExp 构造函数的属性。

属性 描述
global 是否针对字符串中的所有可能匹配项测试正则表达式,或者仅针对第一个匹配项。
ignoreCase 尝试在字符串中匹配时是否忽略大小写。
lastIndex 下一个匹配开始的索引。
multiline (也通过 RegExp.$*) 是否在多行字符串中搜索。
source 模式的文本。

valueOf() 方法不再专门用于 RegExp。它使用 Object.prototype.valueOf(),后者返回自身。

Function

  • 函数的 arity 属性已废弃。请改用 length

Object

属性 描述 替代方案
__count__ 返回用户定义对象上直接可枚举属性的数量。 Object.keys()
__parent__ 指向对象的上下文。 无直接替代方案
__iterator__ 旧版迭代器一起使用。 Symbol.iterator 和新的迭代协议
__noSuchMethod__ 当不存在的属性被作为方法调用时调用的方法。 Proxy
Object.prototype.eval() 在指定对象的上下文中评估 JavaScript 代码字符串。 无直接替代方案
Object.observe() 异步观察对象的更改。 Proxy
Object.unobserve() 移除观察者。 Proxy
Object.getNotifier() 创建一个通知器对象,允许通过 Object.observe() 合成触发可观察的更改。 无直接替代方案
Object.prototype.watch() 将处理程序回调附加到属性,当属性被赋值时调用。 Proxy
Object.prototype.unwatch() 移除属性上的 watch 处理程序。 Proxy

String

WeakMap

  • WeakMap.prototype.clear() 在 Firefox 20 中添加,在 Firefox 46 中移除。无法遍历 WeakMap 中的所有键。

Date

  • Date.prototype.toLocaleFormat()(它使用的格式字符串与 C 语言中的 strftime() 函数预期的格式相同)已废弃。请改用 toLocaleString()Intl.DateTimeFormat

Array

  • 非标准的 Array 通用方法,如 Array.slice(myArr, 0, 12)Array.forEach(myArr, myFn) 等,在 Firefox 1.5 (JavaScript 1.6) 中引入,在 Firefox 68 中弃用,并在 Firefox 71 中移除。您可以改用 Array.prototype 上的方法与 Function.call 结合使用。
属性 描述 替代方案
Array.observe() 异步观察数组的更改。 Proxy
Array.unobserve() 移除观察者。 Proxy

Number

Proxy

  • Proxy.createProxy.createFunction 已废弃。请改用 Proxy() 构造函数。
  • 以下陷阱已废弃:

ParallelArray

  • ParallelArray 已废弃。

语句

  • for each...in 已废弃。请改用 for...of
  • let 块和 let 表达式已废弃。
  • 表达式闭包(function () 1 作为 function () { return 1; } 的简写)已废弃。请改用常规函数箭头函数

获取源文本

数组、数字、字符串等的 toSource() 方法和 uneval() 全局函数已废弃。请改用 toString(),或编写您自己的序列化方法。

旧版生成器和迭代器

旧版生成器函数语句和旧版生成器函数表达式已移除。旧版生成器函数语法重用 function 关键字,当函数体内有一个或多个 yield 表达式时,它会自动成为生成器函数——这现在是一个语法错误。请改用 function* 语句function* 表达式

数组推导和生成器推导已移除。

js
// Legacy array comprehensions
[for (x of iterable) x]
[for (x of iterable) if (condition) x]
[for (x of iterable) for (y of iterable) x + y]

// Legacy generator comprehensions
(for (x of iterable) x)
(for (x of iterable) if (condition) x)
(for (x of iterable) for (y of iterable) x + y)

Firefox 在 26 版本之前实现了一个与标准迭代器协议类似的迭代器协议。当一个对象实现了 next() 方法时,它就是一个旧版迭代器,该方法在每次调用时产生一个值,并在迭代结束时抛出 StopIteration 对象。这个旧版迭代器协议与标准迭代器协议的不同之处在于:

  • 值直接作为 next() 调用的返回值返回,而不是作为 IteratorResult 对象的 value 属性。
  • 迭代终止通过抛出 StopIteration 对象来表示,而不是通过 IteratorResult 对象的 done 属性。

此特性以及 StopIteration 全局构造函数已在 Firefox 58+ 中移除。为了面向未来的使用,请考虑使用 for...of 循环和迭代器协议

Sharp 变量

Sharp 变量已废弃。为了创建循环结构,请改用临时变量。