上节我们一起研究了this这个小兄弟,得出一个结论,this指向调用this所在函数(或作用域)的那个对象或作用域。不太理解的朋友可以看看上节的内容,这次我们主要探讨一下call(),apply(),bind()三兄弟的用法。先上一波定义:
1.方法定义(摘自http://www.cnblogs.com/jingwhale/p/4604917.html?utm_source=tuicool&utm_medium=referral)
call方法:
语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]])
定义:调用一个对象的一个方法,以另一个对象替换当前对象。
说明:
call 方法可以用来代替另一个对象调用一个方法。call
方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。
如果没有提供 thisObj 参数,那么 Global 对象被用作
thisObj。
apply方法:
语法:apply([thisObj[,argArray]])
定义:应用某一对象的一个方法,用另一个对象替换当前对象。
说明:
如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。
如果没有提供
argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数。
(吐槽一下这个定义,看的一头雾水不说,而且我不觉得调用和应用有什么区别,难道是翻译的区别?)
2.应用场景(和原作者出入非常大,各位博友有不同意见的一定要说明)
我把call()和apply()这两种方法的机制习惯上成为对象冒充,实际上就是用来设置函数体内this对象的值,比如apply()函数就接收两个参数,一个是在其中运行函数的作用域,另一个是参数数组。
1 function sum(num1,num2){ 2 return num1+num2 3 } 4 function callSum(num1,num2){ 5 return sum.call(this,num1,num2) 6 } 7 console.log(callSum(1,2)) //3
如上代码,callSum是可以调用sum()函数的,并且会给sum()传递两个参数,我们仔细分析一下这段代码看看,首先会声明两个函数sum和callSum,然后会指向第7行的callSum函数,并且传入两个参数sum1,sum2,在这个函数内部执行sum.call(),因为this是在callSum函数内部调用的,所以this指向callSum()。接下来就是重头戏了,系统开始执行sum函数,两个参数不是来自调用sum()的作用域window,而是来自冒充这个本应该是sum参数作用域window的callSum,这就是对象冒充,用call()函数的第一个参数的作用域冒充原本函数应该执行的作用域。
就相当于callSum()是这样写的:
1 function callSum(num1,num2){ 2 return sum(num1,num2) 3 }
很明显可以看出来,num1和num2是来自于callSum()的参数传递。
再看一个栗子:
1 window.color="window_blue"; 2 var obj={ 3 color:"obj_red" 4 }; 5 function sayColor () { 6 console.log(this); 7 console.log(this.color); 8 }; 9 10 sayColor(); //window_blue 11 sayColor.call(window); //window_blue 12 sayColor.call(obj); //obj_red
这次看是不是清晰多了,分别调用sayColor()方法,sayColor函数里的this是指向window的,但是12行用obj去冒充sayColor()函数执行的this,于是就得到了obj.color的值。
再来看个更复杂的:
1 <input type="text" id="myText" value="input text"> 2 <script> 3 function Obj(){this.value="对象!";} 4 var value="global 变量"; 5 function Fun1(){console.log(this.value);} 6 7 window.Fun1(); //global 变量 8 Fun1.call(window); //global 变量 9 10 Fun1.call(new Obj()); //对象! 11 window.onload=function(){ 12 Fun1.call(document.getElementById('myText')); //input text 13 } 14 var func=new function(){this.a="func"} 15 var myfunc=function(x){ 16 var a="myfunc"; 17 alert(this.a); 18 alert(x); 19 } 20 myfunc.call(func,"var"); 21 <script/>
这段代码是随便网上找了段,一起看看吧:
第三行定义了一个value为'对象!'的对象Obj,第四行定义了一个全局变量value,赋值为"global 变量",第五行创建一个名为Fun1的函数,打印出this.value的值(this默认指向window,还不理解的建议看下上节关于this的讨论),第七行和第八行分别是普通调用Fun1和用window代替默认this指向(依然是window)后调用Fun1,得到的值当然是window下的value的值。
第十行用Obj()的一个对象来冒充window,得到Obj构造器中的value,依次类推,就不一一分析了,也佐证了我们刚才的推论。
apply大体和call都是一样的,我们来说一说他两之间的区别即可:
apply()函数和call()函数的区别在于传递参数的不同,call函数的参数需要全部写出来来传递给执行的函数,apply()是将参数作为一个数组进行传递,例如:
1 var test="Tony"; 2 var myobj={ 3 test : "Tom" 4 }; 5 function doSomething(name, age){ 6 alert(this.test + ":" + name + age); 7 } 8 doSomething("Tony",23);//普通调用 结果Tony:Tony23 9 doSomething.call(myobj,"Tony",23);//call调用结果Tom:Tony23 10 doSomething.apply(myobj,["Tony",23]);//apply调用 结果与call相同
apply的数组参数也可以写为arguments作为一个类参进行传递,得到的结果是一样的。
下节来说说arguments参数和bind()的用法,在520这个满屏秀恩爱的日子里,作为一个没有对象的单身狗一直扯对象有点不太好了,明天再见喽!
javascript-this,call,apply,bind简述3 http://www.cnblogs.com/wangxiaosan/p/5519928.html