为什么不推荐使用 String.prototype.substr()?

Why is String.prototype.substr() deprecated?

ECMAScript 标准 here 中提到:

... These features are not considered part of the core ECMAScript language. Programmers should not use or assume the existence of these features and behaviours when writing new ECMAScript code. ECMAScript implementations are discouraged from implementing these features unless the implementation is part of a web browser or is required to run the same legacy ECMAScript code that web browsers encounter.

MDN上也有红色警告:String.prototype.substr() MDN doc

有谁知道为什么(ECMAScript 标准这么说)程序员不应该使用或假设 String.prototype.substr 的存在?

因为它从来都不是标准化语言的一部分。它根本不在 ECMAScript 1 或 2 规范中,仅出现在 ECMAScript 3 的 B.2 节(“附加属性”)(以及类似附件中的后续版本,直至 today [ES2022 草案截至这篇文章]),它说:¹

Some implementations of ECMAScript have included additional properties for some of the standard native objects. This non-normative annex suggests uniform semantics for such properties without making the properties or their semantics part of this standard.

此外,substrsubstring and slice 在很大程度上是多余的,但第二个参数具有不同的含义。

从实用的角度来说,如果您发现完全主流的 JavaScript 引擎没有提供它,我会感到惊讶;但如果 JavaScript 针对 embedded/constrained 环境的引擎使用 没有 提供它,我不会感到惊讶。


¹ 该措辞最近更改为:

The ECMAScript language syntax and semantics defined in this annex are required when the ECMAScript host is a web browser. The content of this annex is normative but optional if the ECMAScript host is not a web browser.


NOTE This annex describes various legacy features and other characteristics of web browser ECMAScript hosts. All of the language features and behaviours specified in this annex have one or more undesirable characteristics and in the absence of legacy usage would be removed from this specification. However, the usage of these features by large numbers of existing web pages means that web browsers must continue to support them. The specifications in this annex define the requirements for interoperable implementations of these legacy features.

These features are not considered part of the core ECMAScript language. Programmers should not use or assume the existence of these features and behaviours when writing new ECMAScript code. ECMAScript implementations are discouraged from implementing these features unless the implementation is part of a web browser or is required to run the same legacy ECMAScript code that web browsers encounter.


我已将此声明添加为 top-level ambient.d.ts 文件中的环境声明:

interface String {
  /**
   * Gets a substring beginning at the specified location and having the specified length.
   * (deprecation removed)
   * @param from The starting position of the desired substring. The index of the first character in the string is zero.
   * @param length The number of characters to include in the returned substring.
   */
  substr(from: number, length?: number): string;
}

我发现 substr 非常有用。指定字符串的长度比指定字符串的结束索引通常要简洁得多。如果 substr 真的从浏览器中删除或 Node.js JavaScript 支持,我怀疑我们中的许多人都会简单地 monkey-patch substr 重新存在。

substr的主要优点是可以指定负数开始位置! 对 substring 做同样的事情太糟糕了。