call和apply的作用是:更改函数运行时候的上下文对象,换句话说,就是更改函数运行时候的this指向
call 和 apply 是为了动态改变 this 而出现的,当一个 object 没有某个方法,但是其他的有,我们可以借助call或apply用其它对象的方法来操作。
function Person(name) { this.name = name; this.say = function () { console.log("我叫:" + this.name) } } let p1 = new Person("benben"); p1.say(); // 我叫:benben let p2 = { name: "大宝" } p1.say.call(p2) //我叫:大宝
p1.say.apply(p2) //我叫:大宝
call和apply的区别: 他们的作用完全一样,只是参数不一样,当函数的参数明确的时候,用call,参数不明确的时候,用apply
function func(x,y){ console.log(x+y); } func.call(this,1,2); //3 func.apply(this,[1,2]); //3
apply可以用来数组的合并
let arr1 = [1,2,3]; let arr2 = [4,5,6]; Array.prototype.push.apply(arr1,arr2) //会对原数组有arr1影响 console.log(arr1);//[1,2,3,4,5,6] console.log(arr2);//[4,5,6]
为什么不用js的原生push()呢,因为原生push(),参数添加的是个数组
let arr3 = [1,2,3]; let arr4 = [4,5,6]; arr3.push(arr4); console.log(arr3); //[1, 2, 3, Array(3)] console.log(arr4); //4,5,6
为什么不用原生的concat(),因为不会对原数组有影响,返回的是一个新数组
let arr5 = [1,2,3]; let arr6 = [4,5,6]; let arr7 = arr5.concat(arr6); console.log(arr5); //[1, 2, 3] console.log(arr6); //[4, 5, 6] console.log(arr7); //[1, 2, 3, 4, 5, 6]
将伪数组转换成数组:用Array.prototype.slice.call(nodeList)
let showNode = document.getElementsByTagName("*"); let showNodeArray = Array.prototype.slice.call(showNode); showNodeArray.push(22); console.log(showNodeArray); [html, head, meta, meta, meta, title, body, script, 22]
MDN的解释是:bind()方法会创建一个新函数,称为绑定函数,当调用这个绑定函数时,绑定函数会以创建它时传入 bind()方法的第一个参数作为 this,传入 bind() 方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数
var x= 10; function showBind() { return this.x; } var foo = { x: 22 } console.log( showBind());// 10 let funcBind = showBind.bind(foo); console.log(funcBind()); //22
apply、call、bind比较
- apply 、 call 、bind 三者都是用来改变函数的this对象的指向的;
- apply 、 call 、bind 三者第一个参数都是this要指向的对象,也就是想指定的上下文;
- apply 、 call 、bind 三者都可以利用后续参数传参;
- bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用