zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Oracle SQL语句大全—查看表空间
    Class to disable copy and assign constructor
    在moss上自己总结了点小经验。。高手可以飘过 转贴
    在MOSS中直接嵌入ASP.NET Page zt
    Project Web Access 2007自定义FORM验证登录实现 zt
    SharePoint Portal Server 2003 中的单一登录 zt
    vs2008 开发 MOSS 顺序工作流
    VS2008开发MOSS工作流几个需要注意的地方
    向MOSS页面中添加服务器端代码的另外一种方式 zt
    状态机工作流的 SpecialPermissions
  • 原文地址:https://www.cnblogs.com/wangxiaosan/p/5513302.html
Copyright © 2011-2022 走看看