js call 和apply
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了js call 和apply相关的知识,希望对你有一定的参考价值。
ECMAScript3 给Function原型上定义了两个方法,他们是Function.prototype.call和Function.prototype.apply。
- call和apply的区别
1 var func =function(a,b,c){ 2 alert([a,b,c]); 3 }; 4 func.apply(null,[1,2,3]);//apply 5 6 7 var func =function(a,b,c){ 8 alert([a,b,c]); 9 }; 10 func.call(null,1,2,3);//call
apply::两个参数,第一个参数:指定了函数体内this对象的指向;
第二个参数:一个带下标的集合,可以为数组,也可以为伪数组
call:多个参数:第一个参数:指定了函数体内this对象的指向;
第二个参数开始往后,每一个参数被依次传入函数;
call和apply传入的第一个参数为null,函数体内this会指向默认的宿主对象,在浏览器中则是window
如果在严格模式下,函数体内的this还是为null 1 var func = function(a,b,c){
2 alert(this === window);//true 3 }; 4 5 func.apply(null,[1,2,3]) 6 7 var func = function(a,b,c){ 8 "use stract";//如果在严格模式下,函数体内的this还是为null 9 alert(this === null);//true 10 }; 11 func.apply(null,[1,2,3]);
- call和apply的用途
1.改变this的指向
1 var obj1 = { 2 name:"seven" 3 }; 4 5 var oj2 = { 6 name:"anne" 7 }; 8 9 window.name = "window"; 10 11 var getName = function(){ 12 alert(this.name) 13 }; 14 15 getName();//window 16 getName.call(obj1);//seven 17 getName.apply(obj2);//anne
在实际开发中,经常会遇到this指向被不经意改变的场景,比如,有一个div节点,div节点的onclick事件中的this本来指向这个div的:
1 dcument.getElementById("div1").onclick=function(){ 2 alert(this.id);//div1 3 } 4 //加入改时间函数中有一个内部函数func,在实践内部调用func函数时,func函数体内的this就指向了window,而不是我们预期的div 5 6 document.getElementById("div1").oonclick = function(){ 7 alert(this.id);//div1 8 var func = function(){ 9 alert(this.id) //undefined 10 }; 11 func(); 12 }; 13 //这时候我们用call来修正func函数内的this,使其指向div 14 document.getElementById("div1").onclick=function(){ 15 var func = function(){ 16 alert(this.id);//div1 17 }; 18 func.call(this); 19 }
使用call来修正this的场景,我们并不是第一次遇到,
1 document.getElementById = (function(){ 2 return function(){ 3 return func.apply(document,arguments); 4 } 5 })(document.getElementById); 6 7 var getId =document.getElementById; 8 var div = getId("div1"); 9 alert(div.id); //div1
2.Function.prototype.bind
大部分浏览器都实现了内置的Function.prototype.bind,用来指定函数内部的this指向,即使没有原生的Function.prototype.bind实现。
1 Function.prototype.bind= function(context){ 2 var self = this;//保存原函数 3 return function(){//返回一个新函数 4 return self.apply(context,arguments);//执行新的函数的时候,会把之前的context当做新函数体内的this 5 }; 6 } 7 8 var obj = { 9 name:"seve" 10 }; 11 12 var a = function(){ 13 alert(this.name);//seve 14 }.bind(obj); 15 16 a();
我们通过Function.prototype.bind来“包装”func函数,并且传入一个对象context当作参数,这个context对象就是我们想修正的this对象。
在Function.prototype.bind的内部实现中,我们先把func函数的引用保存起来,然后返回一个新函数。当我们在将来执行a函数时,实际上先执行的是这个刚刚返回的新函数。在新函数内部,self.apply(context,arguments)这句话代码是执行原来的a函数,并且指定context对象为a函数体内的this.
下面是复杂一点的实现:
以上是关于js call 和apply的主要内容,如果未能解决你的问题,请参考以下文章