Nodejs中array.slice的类里为什么不能这么用
Nodejs中array.slice的类里为什么不能这么用
var invokeCb = function(cb) {
console.log( arguments.slice(1));
console.log( Array.prototype.slice.call(arguments, 1));
}
invokeCb(‘aa’,‘bb’,‘cc’,‘dd’);
为什么 console.log( arguments.slice(1)); 这句是错误 而 console.log( Array.prototype.slice.call(arguments, 1)); 而这句是正常的
求解
当然可以。让我们来详细分析一下这段代码,并解释为什么 console.log( arguments.slice(1));
会出错,而 console.log( Array.prototype.slice.call(arguments, 1));
却是正确的。
问题背景
在JavaScript中,函数内的 arguments
对象是一个类数组对象,它包含了传递给函数的所有参数。然而,arguments
对象并不是一个真正的数组,因此它没有数组原型上的方法(如 slice
)。
示例代码分析
var invokeCb = function(cb) {
console.log( arguments.slice(1));
console.log( Array.prototype.slice.call(arguments, 1));
}
invokeCb('aa', 'bb', 'cc', 'dd');
第一行输出:console.log( arguments.slice(1));
在这行代码中,我们尝试直接调用 arguments.slice(1)
。由于 arguments
对象不是一个真正的数组,它并没有 slice
方法。因此,这会导致一个错误,类似于:
TypeError: arguments.slice is not a function
第二行输出:console.log( Array.prototype.slice.call(arguments, 1));
在这行代码中,我们使用了 Array.prototype.slice.call(arguments, 1)
的方式来调用 slice
方法。这种方式利用了 call
方法将 slice
方法绑定到 arguments
对象上,并传递了需要切片的起始索引 1
。这样,即使 arguments
不是一个真正的数组,我们也能通过借用数组的方法来操作它。
正确的输出
当你运行这段代码时,第二行输出将是:
[ 'bb', 'cc', 'dd' ]
这是因为 Array.prototype.slice.call(arguments, 1)
将 arguments
对象当作数组来处理,从索引 1
开始获取所有元素。
总结
总结来说,arguments
对象虽然看起来像一个数组,但它实际上是一个类数组对象。为了正确地使用数组方法(如 slice
),我们需要借助 Array.prototype
上的方法,或者将其转换为真正的数组。例如,可以使用 [...arguments].slice(1)
或 Array.from(arguments).slice(1)
来实现同样的效果。
给你讲的详细点,好理解~ 函数的 arguments 对象并不是一个数组,类似数组具有数字索引和length。只有真正的数组对象才slice方法。 那么通过Array.prototype.slice.call调用,把arguments对象转化为真正的Array对象。 类似下面代码功能 var args = []; for (var i = 1; i < arguments.length; i++) { args.push(arguments[i]); } 一般情况下面2种方法都能实现arguments转数组 var args = Array.prototype.slice.call(arguments); var args = [].slice.call(arguments, 1); 一般情况下arguments.length较小时用var args = [].slice.call(arguments, 1); 性能比较好。 当arguments.length比较大时var args = Array.prototype.slice.call(arguments);性能好。