Array.prototype.slice.apply(arguments)和[].slice.apply(arguments)解析

我们知道,函数内部 arguments 是一个类数组对象,不是真正的数组,因此也无法使用数组的各种方法。想详细了解 argument 对象可以前往函数中的 arguments

(function fun(){
	console.log(arguments.reverse());		//报错
})();

Array.prototype.slice.apply(arguments)[].slice.apply(arguments)可以将 arguments 转换为一个真正的数组。

(function fun(){
	var arr = Array.prototype.slice.apply(arguments);
	var arr2 = [].slice.apply(arguments);
	console.log(arr);		//[18,23]
	console.log(arr.reverse());		//[23,18]
	console.log(arr2);		//[18,23]
	console.log(arr2.reverse());		//[23,18]
})(18,23);

当然这里用 call 方法或者 bind 方法也可以等到一样的结果。这三个方法的区别和使用方法可以参照apply()、call()与bind()的用法与区别

(function fun(){
	var arr = Array.prototype.slice.apply(arguments);
	var arr2 = Array.prototype.slice.call(arguments);
	var arr3 = Array.prototype.slice.bind(arguments)();
	console.log(arr);		//[18,23]
	console.log(arr.reverse());		//[23,18]
	console.log(arr2);		//[18,23]
	console.log(arr2.reverse());		//[23,18]
	console.log(arr3);		//[18,23]
	console.log(arr3.reverse());		//[23,18]
})(18,23);
Array.prototype.slice.apply(arguments)

我们从外到里看一下这个式子。
apply() 方法能够将函数内部的 this 绑定为指定对象。这个方法接收两个参数:第一个是新的 this 对象,第二个是一个参数数组,如果函数调用不需要参数的话,则可以省略。因此这里是将 Array.prototype.slice() 内部的 this 对象绑定为 arguments 。
slice() 方法可从已有的数组中返回选定的元素。这个方法接收两个可选的参数:第一个是开始的选定的位置,第二个是结束的位置(不包括)。如果两个参数都不传,则默认从0开始直到结束。
我们知道,当一个函数调用存在上下文对象,就会应用隐式绑定规则,将函数内部的 this 绑定到这个上下文对象。想了解 this 的绑定规则可以前往JavaScript 中判断一个函数的 this 绑定。但是这个式子却将 this 对象绑定为 arguments 并且将其转化为数组,为什么要这样做呢?我们测试一下。

var arr = [1,2,3];
var arr2 = [4,5];
console.log(arr2.slice());		//[4,5]
console.log(arr2.slice.apply(arr));		//[1,2,3]

从上面可以看出,将 slice() 的 this 对象从 arr2 变为 arr 后,slice() 方法的作用对象就变成 arr 了。我们可以简单猜测一下 slice() 方法的实现代码:

Array.prototype.slice = function(start,end){
	var result = new Array();
	start = start || 0;
	end = end || this.length; 
	for(var i = start; i < end; i++){
		result.push(this[i]);
	}
	return result;
}

从上面代码就可以看出为什么 Array.prototype.slice.apply(arguments) 为什么可以将 arguments 转化为一个真正的数组,它首先创建一个数组,然后将 this 对象按下标一个一个推入数组中,最后返回这个数组。

[].slice.apply(arguments)

我们知道,每当代码读取某个对象的某个属性时,都会执行一次搜索,目标是具有给定名字的属性。搜索首先从对象实例本身开始。如果在实例中找到了具有给定名字的属性,则返回该属性的值;如果没有找到,则继续搜索指针指向的原型对象,在原型对象中查找具有给定名字的属性。如果在原型对象中找到了这个属性,则返回该属性的值。
[] 是一个空数组,它的原型对象是 Array.prototype,我们可以测试一下。

console.log([].__proto__ === Array.prototype);		//true

因此 [].slice.apply(arguments) 本质上跟 Array.prototype.slice.apply(arguments) 是一样的,目的都是调用 slice() 这个方法。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值