首先call和apply的作用是一样的,只是传参数的方式不同而已,举个例子
var arr1 = [1,2,3];
Array.prototype.push.apply(arr1,[4,5,6])
//Array.prototype.push.call(arr1,4,5,6)
call和apply的实现原理都是改变参数中的对象指向,指向调用call或apply的Function对象中的this
function person(name){
this.name = name
}
function male(){}
var male1 = new male()
person.call(male1,"xujizhong")
male1.name//"xujizhong"
上面代码中将male这个对象指向了person中的this,所以相当于运行了 male.name = name,而call中传入了参数"xujizhong",所以male1.name的输出结果为"xujizhong"
比较经典的例子像Array.prototype.slice.call(arguments),可以将类数组转换成数组(类数组必须包含length属性)
var arr2 = {1: 1, 2: 2, 5: 5, aa: "aa", length: 10}
var arr3 = Array.prototype.slice.call(arr2)
//[empty, 1, 2, empty × 2, 5, empty × 4]
//1:1
//2:2
//5:5
//length:10
arr[0] //undefined
arr[1] //1
Array.prototype.slice方法将对象中的非索引的对象删除并且对应length在没有索引的位置加入了空位置,并且因为slice方法返回的是数组,所以获得的arr3为一个数组
也可以利用Array.prototype.filter从不返回稀疏数组的特性来获得一个非稀疏数组的数组
var arr2 = {1: 1, 2: 2, 5: 5, aa: "aa", length: 10}
var arr4 = Array.prototype.filter.call(arr2,function(){return true})
// [1, 2, 5]
//0:1
//1:2
//2:5
//length:3
网友评论