JavaScript数组的splice()方法的参数问题

发布于 2022-09-07 21:54:05 字数 1219 浏览 19 评论 0

最近在使用splice方法的时候,遇到了一个百思不得其解的一个问题?话不多说上代码:
<script>

    var arr=[1,2,3,7,8,9,2,6,9,9,8,5,2,3,1];
    console.log('原始数据',arr);

    arr.splice(undefined,1)
    console.log('传入undefined',arr);

    arr.splice(null,1)
    console.log('传入null',arr);

    arr.splice(NaN,1)
    console.log('传入NaN',arr);

    arr.splice(true,1)
    console.log('传入true',arr);

    arr.splice(false,1)
    console.log('传入false',arr);

    arr.splice(" ",1)
    console.log('传入空格字符串',arr);

    arr.splice('',1)
    console.log('传入空字符串',arr);

    arr.splice(new Object(),1)
    console.log('传入空对象',arr);

    arr.splice([],1)
    console.log('传入空数组',arr);

    arr.splice(2.3,1)
    console.log('传入小数',arr);        

    arr.splice(-2.3,1)
    console.log('传入负小数',arr);

    arr.splice(-2,1)
    console.log('传入负整数',arr);        

    arr.splice(-2,1)
    console.log('传入负整数',arr);
</script>

打印出的结果如下图;

clipboard.png
这个时候我有点晕了,splice方法第一个参数是指定替换或删除的起始位置,按理是一个索引值,对于非数字型的参数,如果它调用的是number对象的话,undefined转换成数字应该是NaN啊,应该会报错啊,但是打印台还是正常打印出结果

上面的情况都有一个共同点,好像都转换成了数字0了,才有打印台的结果表现
有没有大佬解释一下,我看MDN上面也没有这种情况的说明

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

三生殊途 2022-09-14 21:54:06

上面的情况都有一个共同点,好像都转换成了数字0了,才有打印台的结果表现

显然并不都是把start当成0处理的....

1.先说MDN上写了的,也就是负整数的情况。

对于start,MDN描述为:

...如果该参数为负数,则表示从原数组中的倒数第几个元素开始提取,slice(-2)表示提取原数组中的倒数第二个元素到最后一个元素(包含最后一个元素)。

也就是对于题目中arr.splice(-2, 1)的例子,提取之前arr = [9, 8, 2, 1],此时start为-2 + 4 = 3,因此行为等价于arr.splice(3, 1),结果2被抽走了,符合描述。

2.剩下的都是MDN未描述清楚的,这里要去看ECMA-262规范,这里以最新的规范做说明。

首先找到22.1.3.25 Array.prototype.splice的描述:

关于start的处理在这两步完成,最后起作用的值是actualStart。

clipboard.png

所以第一步是把start进行ToInteger处理:

clipboard.png

然后发现又进了一个ToNumber处理....

clipboard.png

以入参undefined为例,首先经过ToNumber,返回NaN

然后根据ToInteger的第二点,返回+0

最后根据Splice的第四点,返回min(+0, length),也就是+0

因此undefined作为start传入,最后是被当做+0处理的。

剩下的你自己分析吧...

自此以后,行同陌路 2022-09-14 21:54:06

传送门:Array.prototype.splice

你的问题标准的这两步都说明好啦:
为了方便对应加了前缀ABCDEFG,可以对应起来。

A、Let relativeStart be ? ToInteger(start).
B、If relativeStart < 0, let actualStart be max((len + relativeStart), 0); else let actualStart be min(relativeStart, len).

深入看看ToInteger内部方法。

C、Let number be ? ToNumber(argument).
D、If number is NaN, return +0.
E、If number is +0, -0, +∞, or -∞, return number.
F、Return the number value that is the same sign as number and whose magnitude is floor(abs(number)).

再进一步看看ToNumber内部方法,大致写写了。

FLAG类型结果
GUndefinedNaN
HNull+0
IBooleantrue---1 false---0
JString有效数字转化为相应数字类型。空字符串转化为0。有效数字转化为NaN
KObject先 ToPrimitive(argument, hint Number) ,所得结果再toNumber

回到你的问题。
undefined:对应 C(G)、D。转化为 0
null:对应 C(H)、E。转化为 0
NaN:对应 D。转化为 0
true:对应 C(I)。转化为 1
false:对应 C(I)。转化为 0
" ":对应 C(J)、D。转化为 0
''::对应 C(J)、D。转化为 0
new Object():对应 C(K)、D。转化为 0
[]:对应 C(K)、D。转化为 0
2.3:对应 F。转化为 2
-2.3:对应 F、B。转化为 5-2=3
-2:对应 B。转化为 4-2=2

不醒的梦 2022-09-14 21:54:06

数值为NaN就相当于是0

clipboard.png

负数从后面开始计数

clipboard.png

小数是直接舍弃小数部分

你这个之所以迷惑,主要是样本数据前后有点协同,不好区分

怀中猫帐中妖 2022-09-14 21:54:06

第一个参数进来后会做

  1. 如果是布尔型,true当做1,false当做0
  2. 其余情况使用parseInt处理,如果得到NaN一律当成0处理。否则就用转换后的数值。
惯饮孤独 2022-09-14 21:54:06
echo 1212
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文