今天看到这个用法的时候产生了疑问,
slice 方法可以用来将一个类数组(Array-like)对象/集合转换成一个数组。你只需将该方法绑定到这个对象上。
mdn上给出了一个例子:
function list() {
return Array.prototype.slice.call(arguments);
}
var list1 = list(1, 2, 3); // [1, 2, 3]
我的问题是:
平时更容易遇到fun.call (null, arguments)
这样的用法,因为Function.prototype.call()的用法是
fun.call(thisArg[, arg1[, arg2[, ...]]])
所以遇到把Array.prototype.slice.call(arguments)
这样的把arguments作为在函数运行时指定的this值感觉很别扭,总是想成Array.prototype.slice.call(null, arguments)
这样的,又不知道这样为什么不对?
除了Array.prototype.slice.call(arguments)
这样的用法,那么Array.prototype上其他的方法是不是也可以这样使用呢?比如Array.prototype.splice.call(arguments,1)
?
我分享一下我的想法吧,仅供参考:
第一个问题:
在js中用
call
去掉用函数传的的一个参数就是调用这个函数的对象(即被调用函数的this
指向),应了这句this
谁调用它就指向谁。然后第二个参数开始就是传入函数里的参数。在你上面的代码中:
Array.prototype.slice.call(null, arguments)
相当于是用null
去调用slice
函数,把arguments
作为函数的参数。null
是调用不了这个slice
函数的因为null
既不是数组也不是类数组,所以会报错。第二个问题:
可以的,如下图:
最后附上个链接(翻到文章最下面的小拓展部分)
Array.prototype.slice.call(arguments)
这里其实是把arguments
设置成函数slice
的this
,也就是对arguments
进行slice
操作,从而达到把传入的参数变成array
的目的。而Array.prototype.slice.call(null, arguments)
其实是null.slice(arguments)
, 这个就会throwTypeError
了吧这个问题分成两部分解释
为什么使用call
你已经了解到
另外还知道slice的相关用法
OK,(敲黑板)(划重点)这里使用call并不是那么符合语境的(摔),应该使用绑定
其本质和
是一样的,之所以这样使用,是因为
arguments是什么,什么叫类数组对象
arguments:
全称Function.prototype.arguments(有的地方说是有区别,求哪位大神明示。)其实除去arguments外,还有一些类数组对象,举个栗子
这就是一个简单的类数组对象啦。
说的比较杂,希望能帮到你一二
谢邀。以下是我个人的理解。如果有错误请指正。
首先一点,你可能已经知道了,
.slice
是数组方法,可以用来深拷贝数组。如果直接赋值就是浅拷贝然后,看下
arguments
长啥样儿的就懂了。。JS 中,两种常见的 "array-like object"(像数组一样的对象)一个是arguments
,一个就是nodeList
。他们长这样:
如果一个东西满足这两点:
有数字形式的
key
,从 0 开始有一个
length
属性那么这个东西就是 "array-like object"。"array-like object" 至少有一个好处,就是可以直接构建一个
Array
实例。可以通过Array.from()
或者 ES6 的 "Spread Operator"(也就是...
)来构建。注意:JS 中只允许字符串作为对象的
key
,因此才会是上面的写法。就算你尝试着用数字去做key
,它也会帮你转成字符串的。由于这个东西本身还是
object
,或者说它不是Array
的一个instance
(实例),因此,没法直接调用.slice
方法。Array.prototype.slice
返回的是一个Function
实例,调用它的call
方法是为了改变.slice
方法的this
,也就是说,改变一下谁来调用slice
。因此,
.call(arguments)
这个写法并不比别扭。你如果第一个参数传入null
是肯定不行的,因为null
既没有.slice
方法,也不能构建成一个array
。"array-like object" 虽然也没有slice
方法,但至少它有上面说到的 "数字key" 和 "length" 属性,因此可以构建一个array
个人看来,不妨把它简单理解为:
Array.prototype.slice(arguments)
做的事儿就是:至于你提到的
Array.prototype.splice.call(arguments,1)
,没有问题。把arguments
作为this
,就用arguments
构建一个Array
实例,也就有了splice
方法。不妨也把它理解成:谢邀,感觉楼上兄弟们回答的都很好。
先说一下
[].slice(start, end)
接收的参数,start
为开始索引,end
为结束索引,而且取前不取后,如果省略参数,则拷贝一个数组的副本。前面你也说了
call
的用法,fn.call(thisArgthisArg[, arg1[, arg2[, ...]]])
;下面我们用call调用slice方法:对应开始填参数————第一个为要截取的对象(arguments对象),第二个为开始索引,第三个参数为结束索引。
下面我们省略start和end
类似的,我们使用document.getElementsByTagName获得的也是一个类数组,我们可以把他转为原生数组
我感觉你是自己对于数组的方法没有深入的理解,而不是call的用法,理解好数组方法的各个参数的意义,对应着填到call或者apply的参数位置,也就好理解了。