javascript-this,call,apply,bind简述2

上节我们一起研究了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

 

posted @ 2016-05-20 20:02  王小伞  阅读(330)  评论(0编辑  收藏  举报