slice.call()这个方法第一次接触的时候很容易迷惑,它使arguments转换为array;更具体的理解是:
==》是能够将具有length属性的arguments转换为数组, 可以理解为 arguments.toArray().slice());
==>所以,这个过程我们是不是可以理解为 Array.prototype.slice.call(arguments)的实现过程就是把传入进来的具有length属性的第一个参数arguments转换为数组,再调用它的slice(截取)方法;
本人也看了不少教程和文章,下面分享下感觉比较理解的原理解释:
1. slice方法的内部实现(原理)
Array.prototype.slice = function(start,end){
var result = new Array();
start = start || 0;
end = end || this.length;
// this指向调用的对象,当用了call后,能够改变this的指向,也就是指向传进来的对象,这是关键
for(var i = start; i < end; i++)
{
result.push(this[i]);
}
return result;
}
所以整个过程可以分2步进行理解了
Array.prototype.slice.call(arguments)
第一步: 其中,arguments是一个具有length属性的对象, 通过call 这个方法,把arguments 指向了Array.prototype.slice方法的作用域,也就是说通过call方法,让Array.prototype.slice对arguments对象进行操作
理解第二步: Array.prototype.slice就是对该对象使用Array类的slice方法。但是呢arguments它又不是个Array对象,而是object;
所以我们没法用arguments.slice()方法,会报错。我们需要使用Array.prototype.slice, 它的作用就是第一步把arguments转换为一个Array对象,第二步对转换后的Array对象使用slice方法。
但是需要注意的是,一定要有length属性:
var my_object = {
'0': 'zero',
'1': 'one',
'2': 'two',
'3': 'three',
'4': 'four',
length: 5
};
let a = Array.prototype.slice.call(my_object,3)
a
result:
[ 'three', 'four' ]
如果没有length
var my_object = {
'0': 'zero',
'1': 'one',
'2': 'two',
'3': 'three',
'4': 'four',
};
let a = Array.prototype.slice.call(my_object,3)
a
result:
[]
应用:那为什么我们要用slice.call()的方法呢?以一个具体的应用为案例:计算总和。
function addTwoNumbers(num1,num2){
return num1+num2;
}
addTwoNumbers(24,25)
如果我们想加四个数字怎么办? 有两个方式:1. 声明一个全新的函数,分配四个变量;2. 在大dTwoNumbers这个函数中再套用一次“ addTwoNumbers”函数:
function addTwoNumbers(num1,num2){
return num1+num2;
}
addTwoNumbers(addTwoNumbers(24,25),addTwoNumbers(26,27));
那如果想五个数值相加呢?这种做法显然不够明智;再写一个新的函数也非常麻烦,这时候我们可以采用slice.call()的方式
function addNumbers(){
var argsArray = Array.prototype.slice.call(arguments);
return argsArray.reduce((prev,cur)=>prev+cur);
}
addNumbers(24,25,26,27);
reference:
https://www.cnblogs.com/wphl-27/p/10336591.html