ChatGPT解决这个技术问题 Extra ChatGPT

String.slice 和 String.substring 有什么区别?

有谁知道这两种方法有什么区别?

String.prototype.slice
String.prototype.substring
这是 JavaScript 设计不佳的一个例子,我们最终得到了三种方法,它们都做同样的事情,但有不同的怪癖。 IMO slice 是具有最少意外行为的一个。
IMO 子字符串用于从 idx 到 end 的子字符串一目了然。尤其是对于菜鸟
根据this websiteslice实际上可以代替substring,没有理由使用它。
@AmolMKulkarni 一点也不真实。如果您尝试 var a = "asdf".substring(-1);,它会被视为 var a = "asdf".substring(0);。没有抛出异常。如果您使用 var a = "asdf".substring(2, -1);,它会使用 0 代替 -1(如前所述),并交换参数,使其行为类似于 var a = "asdf".substring(0, 2);。我什至在 IE 8 上尝试了这些,并且毫无例外地得到了结果
“我什至在 IE 8 上尝试过这些”——我喜欢编程。

S
Solomon Ucko

slice() 的工作方式与 substring() 类似,但有一些不同的行为。

Syntax: string.slice(start, stop);
Syntax: string.substring(start, stop);

他们的共同点:

如果 start 等于 stop:返回一个空字符串 如果 stop 被省略:将字符提取到字符串的末尾 如果任一参数大于字符串的长度,则将使用字符串的长度。

区别 substring()

如果 start > stop,则 substring 将交换这两个参数。如果任一参数为负数或为 NaN,则将其视为 0。

区别 slice()

如果 start > stop, slice() 将返回空字符串。 ("") 如果 start 为负数:从字符串末尾设置 char,与 Firefox 中的 substr() 完全相同。在 Firefox 和 IE 中都观察到了这种行为。如果 stop 为负:将 stop 设置为:string.length – Math.abs(stop)(原始值),除了 ECMA 规范中涵盖的 0(因此,Math.max(0, string.length + stop)) .

来源:Rudimentary Art of Programming & Development: Javascript: substr() v.s. substring()


在您对 slice() 的最后一条注释中,它应该是 string.length - stop
在您关于 slice() 的最后一条注释中,我认为应该是 (string.length – 1) + stop,或者,为了明确表示它是否定的,(string.length – 1) – Math.abs(stop)
@Longpoke:添加了 String.slice 以便有一个与 Array.slice 一致的字符串方法。 substring 一直存在,所以他们没有破坏它并添加了另一种方法。几乎不是一个糟糕的决定,因为 1. 一致性很好 2. 它允许 CoffeeScript 的切片语法在数组和字符串上工作。 @Oriol:编辑它。
Firefox 22 中的子字符串和切片之间似乎存在性能差异。jsperf.com/string-slice-vs-substring
安迪是对的。如果 stop 为负数,stop 将设置为 string.length + stop。记住 stop 是提取最后一个字符之后的索引!
G
Gust van de Wal

TL;博士:

如果您知道要停止(但不包括)的索引(位置),请使用 slice()。

如果您知道要提取的字符的长度,则可以使用 substr(),但不鼓励这样做,因为它已被弃用。

否则,请继续阅读以进行完整比较

句法

string.slice(开始,结束)

string.substr(开始,长度)

string.substring(开始,结束)

注意 #1slice()==substring()

它能做什么?

slice() 提取字符串的一部分并在新字符串中返回提取的部分。

substr() 提取字符串的一部分,从指定位置的字符开始,并返回指定数量的字符。

substring() 提取字符串的一部分并在新字符串中返回提取的部分。

注意 #2slice()==substring()

更改原始字符串?

切片()没有

substr() 没有

substring() 没有

注意事项 #3slice()==substr()==substring()

使用负数作为参数

slice() 选择从字符串末尾开始的字符

substr() 选择从字符串末尾开始的字符

substring() 不执行

注意事项 #4slice()==substr()

如果第一个参数大于第二个

slice() 不执行

substr() 因为第二个参数不是位置,而是长度值,它将照常执行,没有问题

substring() 将交换两个参数,并照常执行

第一个论点

需要切片();起始索引

substr() 需要;起始索引

需要子字符串();起始索引

注意事项 #5slice()==substr()==substring()

第二个论点

切片()可选;结束提取的位置(直到,但不包括)

substr() 可选的;要提取的字符数

substring() 可选的;结束提取的位置(直到,但不包括)

注意 #6slice()==substring()

如果省略第二个参数怎么办?

slice() 选择从开始位置到字符串结尾的所有字符

substr() 选择从开始位置到字符串结尾的所有字符

substring() 选择从开始位置到字符串结尾的所有字符

注意事项 #7slice()==substr()==substring()

因此,您可以说 slice()substr() 之间存在差异,而 substring() 基本上是 slice() 的副本。

如果您想要 substr 的功能:

"foobarbaz".substr(index, length);

不使用已弃用的功能,您可以这样做:

"foobarbaz".substring(index, length + index);

并在所有边缘情况下获得完全相同的结果,例如负索引/长度。


@Killy Source regarding it being a legacy feature您的链接中未提及。
您通过“substring() 基本上是 slice() 的副本”来总结您的冗长答案,但问题正是关于这两者之间的区别。除了隐藏在中间某处的唯一相关片段信息“切片将交换参数”之外,您的其余答案都错过了主题。
@CodeFinity 在我写这篇文章时有一条评论,但有人在 2020 年 7 月将其删除web.archive.org/web/20200704195437/https://…
@Killy:它仍然在兼容性表和侧边栏中。标语不一致。不知道为什么有人将其从一个中删除,而不是其他人,反之亦然。这种不一致有点不幸。横幅出现在所有其他人身上。简而言之,substr 是 ECMA 标准附录 B 的一部分,因此不是核心集市。它给出了它的用法说明:262.ecma-international.org/9.0/… - MDN 说明:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
P
Pang

Ben Nadel 写了一篇很好的文章,他指出了这些函数的参数差异:

String.slice( begin [, end ] )
String.substring( from [, to ] )
String.substr( start [, length ] )

他还指出,如果 slice 的参数是负数,它们会从末尾引用字符串。子字符串和子字符串没有。

Here is his article 关于这个。


这是不正确的, substr 确实处理负参数。 '0123456789'.substr(-3, 2) -> '78'
关于来自 mdn 的 substr “已弃用。不适用于新网站。”
A
AmerllicA

一个答案很好,但需要一点阅读。特别是使用新术语“停止”。

我的 Go - 除了上面丹尼尔的第一个答案之外,按差异组织以使其有用:

1) 负指标。子字符串需要正索引,并将负索引设置为 0。切片的负索引表示从字符串末尾开始的位置。

"1234".substring(-2, -1) == "1234".substring(0,0) == ""
"1234".slice(-2, -1) == "1234".slice(2, 3) == "3"

2) 索引交换。 Substring 将重新排序索引以使第一个索引小于或等于第二个索引。

"1234".substring(3,2) == "1234".substring(2,3) == "3"
"1234".slice(3,2) == ""

--------------------------

一般评论——我觉得奇怪的是第二个索引是切片或子字符串的最后一个字符之后的位置。我希望“1234”.slice(2,2) 返回“3”。这使得安迪的困惑是有道理的——我希望“1234”.slice(2, -1) 返回“34”。是的,这意味着我是 Javascript 新手。这也意味着这种行为:

"1234".slice(-2, -2) == "", "1234".slice(-2, -1) == "3", "1234".slice(-2, -0) == "" <-- you have to use length or omit the argument to get the 4.
"1234".slice(3, -2) == "", "1234".slice(3, -1) == "", "1234".slice(3, -0) == "" <-- same issue, but seems weirder.

我的2c。


F
Fudge

substringslice 之间的区别 - 是它们如何处理国外参数的否定和忽略行:

子字符串(开始,结束)

否定参数被解释为零。太大的值会被截断为字符串的长度:

alert("testme".substring(-2)); // "testme", -2 becomes 0

此外,如果 start > end,则参数互换,即绘图线在 start 和 end 之间返回:

alert("testme".substring(4, -1)); // "test"
// -1 Becomes 0 -> got substring (4, 0)
// 4> 0, so that the arguments are swapped -> substring (0, 4) = "test"

负值从行尾开始测量:

alert("testme".slice(-2)); // "me", from the end position 2
alert("testme".slice(1, -1)); // "estm", from the first position to the one at the end.

它比奇怪的逻辑substring方便得多。

除 IE8- 之外的所有浏览器都支持 substr 的第一个参数的负值。

如果选择这三种方法之一,在大多数情况下使用 - 这将是 slice:否定参数,并且它保持和运行最明显。


A
Ashraf Sada

substr:它让我们可以根据指定的索引获取部分字符串。 substr-string.substr(start,end) 的语法 start - 开始索引告诉获取开始的位置。 end - 结束索引告诉字符串获取的位置。这是可选的。

slice:提供根据指定索引获取部分字符串。它允许我们指定正数和索引。 slice 的语法 - string.slice(start,end) start - start index 告诉提取开始的位置。它是 end - end index 告诉 up to string 提取的位置。这是可选的。在“拼接”中,开始和结束索引都有助于获取正负索引。

字符串中“切片”的示例代码

var str="Javascript";
console.log(str.slice(-5,-1));

output: crip

字符串中“子字符串”的示例代码

var str="Javascript";
console.log(str.substring(1,5));

output: avas

[*注意:负索引从字符串的末尾开始。]


您写的内容是错误的,与问题无关。 substr() 是一个不同的函数,它没有参数“开始,停止”,因为您在答案中错误地陈述:它有参数“开始,长度”。但问题根本不是关于 substr()!幸运的是,9年前已经给出了正确而完整的答案......
V
VLAZ

slice 和 substring 方法之间的唯一区别是参数

两者都采用两个参数,例如 start/from 和 end/to。

您不能将负值作为子字符串方法的第一个参数传递,而是切片方法从末尾遍历它。

切片方法参数详细信息:

论据

start_index 切片应该开始的索引。如果提供的值为负数,则表示从最后一个开始。例如 -1 表示最后一个字符。 end_index 切片结束后的索引。如果未提供切片,将从 start_index 到字符串结尾。在负值的情况下,索引将从字符串的末尾开始测量。

子字符串方法参数详细信息:

论据

from 它应该是一个非负整数来指定子字符串应该从哪里开始的索引。 to 一个可选的非负整数来提供索引,在该索引之前应该完成子字符串。


M
MarredCheese

对于 slice(start, stop),如果 stop 为负数,则 stop 将设置为:

string.length – Math.abs(stop)

而不是:

string.length – 1 – Math.abs(stop)