已弃用和过时的功能
此页面列出了 JavaScript 中已弃用(即,仍然可用,但计划删除)和已过时(即,不再可用)的功能。
已弃用功能
这些已弃用的功能仍然可以使用,但应谨慎使用,因为并非每个 JavaScript 引擎都要求实现这些功能。您应该努力从您的代码中删除对它们的用法。
其中一些已弃用的功能列在 附录 B ECMAScript 规范的节中。本节被描述为规范性可选——即,Web 浏览器主机必须实现这些功能,而非 Web 主机可能不实现。这些功能可能很稳定,因为删除它们会导致向后兼容性问题并破坏旧网站。(JavaScript 的设计目标是“不要破坏 Web”。)尽管如此,它们不是跨平台可移植的,并且可能不受所有分析工具的支持,因此建议您不要使用它们,因为附录 B 的介绍中提到了
… 此附录中指定的所有语言功能和行为都具有一个或多个不可取的特性,并且在没有遗留用法的情况下,将从本规范中删除。…
… 程序员在编写新的 ECMAScript 代码时,不应使用或假设这些功能和行为的存在。…
其他一些功能虽然在主规范正文中,但也标记为规范性可选,不应该依赖它们。
HTML 注释
如果 JavaScript 源代码被解析为脚本,则允许使用 HTML 类似的注释,就像脚本是 <script>
标签的一部分一样。
以下代码在 Web 浏览器(或使用为 Chrome 提供动力的 V8 引擎的 Node.js)中运行时是有效的 JavaScript
<!-- 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
Object.prototype.__proto__
访问器已弃用。请改为使用Object.getPrototypeOf
和Object.setPrototypeOf
。这并不适用于对象字面量中的__proto__
文字键。Object.prototype.__defineGetter__
、Object.prototype.__defineSetter__
、Object.prototype.__lookupGetter__
和Object.prototype.__lookupSetter__
方法已弃用。请改为使用Object.getOwnPropertyDescriptor
和Object.defineProperty
。
String
- HTML 包装器方法,如
String.prototype.fontsize
和String.prototype.big
。 String.prototype.substr
可能不会很快被删除,但它是在附录 B 中定义的,因此是规范性可选的。String.prototype.trimLeft
和String.prototype.trimRight
应该被替换为String.prototype.trimStart
和String.prototype.trimEnd
。
Date
getYear()
和setYear()
方法受到 2000 年问题的影响,已被getFullYear
和setFullYear
取代。toGMTString()
方法已弃用。请改为使用toUTCString()
。
转义序列
- 字符串和正则表达式字面量中的八进制转义序列(\ 后跟一个、两个或三个八进制数字)已弃用。
escape()
和unescape()
函数已弃用。请使用encodeURI()
、encodeURIComponent()
、decodeURI()
或decodeURIComponent()
来编码和解码特殊字符的转义序列。
语句
with
语句已弃用,在严格模式下不可用。
for...in
循环头部的 var
声明中的初始化程序已弃用,在严格模式下会产生语法错误。初始化程序表达式将被求值并赋值给变量,但该值将在循环的第一次迭代中立即被重新赋值。
通常情况下,try...catch
语句的 catch
块不能包含任何与 catch()
中绑定的变量同名的变量声明。扩展语法允许 catch
块包含一个与 catch
绑定的标识符同名的 var
声明的变量,但前提是 catch
绑定是一个简单的标识符,而不是解构模式。但是,这个变量的初始化和赋值只会作用于 catch
绑定的标识符,而不是上层作用域的变量,其行为可能会令人困惑。
var a = 2;
try {
throw 42;
} catch (a) {
var a = 1; // This 1 is assigned to the caught `a`, not the outer `a`.
}
console.log(a); // 2
try {
throw 42;
// 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() |
删除属性上的监视处理程序。 | Proxy |
String
- 非标准字符串通用方法,如
String.slice(myStr, 0, 12)
、String.replace(myStr, /\./g, "!")
等,已在 Firefox 1.5(JavaScript 1.6)中引入,在 Firefox 53 中被弃用,并在 Firefox 68 中被删除。您可以改用String.prototype
上的方法以及Function.call
。 String.prototype.quote
已从 Firefox 37 中删除。String.prototype.search
、String.prototype.match
和String.prototype.replace
中的非标准flags
参数已过时。
WeakMap
WeakMap.prototype.clear()
已在 Firefox 20 中添加,并在 Firefox 46 中删除。无法遍历WeakMap
中的所有键。
Date
Date.prototype.toLocaleFormat()
已过时,它使用与 C 中的strftime()
函数期望的格式相同的格式字符串。请改用toLocaleString()
或Intl.DateTimeFormat
。
Array
Number
Number.toInteger()
已过时。请改用Math.floor
、Math.round
或其他方法。
Proxy
Proxy.create
和Proxy.createFunction
已过时。请改用Proxy()
构造函数。- 以下陷阱已过时
hasOwn
(bug 980565, Firefox 33)。getEnumerablePropertyKeys
(bug 783829, Firefox 37)getOwnPropertyNames
(bug 1007334, Firefox 33)keys
(bug 1007334, Firefox 33)
ParallelArray
ParallelArray
已过时。
语句
for each...in
已过时。请改用for...of
。- let 块和 let 表达式已过时。
- 表达式闭包(
function () 1
作为function () { return 1; }
的简写)已过时。请改用常规的函数
或箭头函数。
获取源文本
数组、数字、字符串等的 toSource()
方法以及 uneval()
全局函数已过时。请改用 toString()
或编写您自己的序列化方法。
传统生成器和迭代器
传统生成器函数语句和传统生成器函数表达式已删除。传统生成器函数语法重新使用 function
关键字,当主体中存在一个或多个 yield
表达式时,它会自动成为生成器函数——这现在是一个语法错误。请改用 function*
语句和 function*
表达式。
数组推导式和生成器推导式已删除。
// 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
循环和迭代器协议。
尖锐变量
尖锐变量已过时。要创建循环结构,请改用临时变量。