• 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

  • 相关阅读:
    Nginx 性能优化有这篇就够了!
    Zabbix Web API Get方法整合
    MySQL利用binlog恢复误操作数据(python脚本)
    Tomcat7 1000并发量配置以及配置优化
    MySQL中 如何查询表名中包含某字段的表
    python异步编程之asyncio(百万并发)
    微信支付开发(7) 刷卡支付
    <Android 基础(二十)> CoordinatorLayout Behavior
    实例解析Docker数据卷+数据卷容器+flocker数据共享+DockerHub操作
    我和滴滴打车司机的那些事
  • 原文地址:https://www.cnblogs.com/wangxiaosan/p/5513302.html
Copyright © 2020-2023  润新知