zoukankan      html  css  js  c++  java
  • JS里面的call, apply以及bind

    参考了这篇文章:http://www.tuicool.com/articles/EVF3Eb

    给几个例子

    function add(a,b)  
    {  
        alert(a+b);  
    }  
    function sub(a,b)  
    {  
        alert(a-b);  
    }  
    add.call(sub,3,1);

    这个运行是什么呢?答案:

    4. 运行的是add.
    
    因为call是运行的调用者。将第一个参数作为this参数来使用。

    再来一个例子

    function Animal(){    
        this.name = "Animal";    
        this.showName = function(){    
            console.log(this.name);    
        }    
    }    
    function Cat(){    
        this.name = "Cat";    
    }    
    var animal = new Animal();    
    var cat = new Cat();
    
    animal.showName.call(cat,",");   
    或者
    animal.showName.apply(cat,[]); 

    答案是:

    Cat。 因为this换做了Cat。

    另外,继承时候用来调用父类的构造函数

    function Animal(name){      
        this.name = name;      
        this.showName = function(){      
            console.log(this.name);      
        }      
    }      
    function Cat(name){    
        Animal.call(this, name);    
    }      
    var cat = new Cat("Black Cat");     
    cat.showName();

    调用完父类之后,cat也有了showName的方法。

    下面这两种调用基本等价:

    myfunc.call(func,"var"," fun");
    myfunc.apply(func,["var"," fun"]);

    关于bind:作用:改变了上下文的this

    bind与call不同点有两个:

    ①bind的返回值是函数。

    //使用bind是 返回改变上下文this后的函数

    //使用call是 改变上下文this并执行函数

    ②后面的参数的使用也有区别

    function f(a,b,c){
        console.log(a,b,c);
    }
    
    var f_Extend = f.bind(null,"extend_A")
    f("A","B","C")  //这里会输出--> A B C
    
    f_Extend("A","B","C")  //这里会输出--> extend_A A B
    
    f_Extend("B","C")  //这里会输出--> extend_A B C
    
    f.call(null,"extend_A") //这里会输出--> extend_A undefined undefined
    
    call 是 把第二个及以后的参数作为f方法的实参传进去
    
    而bind 虽说也是获取第二个及以后的参数用于之后方法的执行,但是f_Extend中传入的实参则是在bind中传入参数的基础上往后排的。

    所以,以下两个是等价的:

    var f_Extend = f.bind(null,"extend_A")
    
    //↓↓↓
    
    var f_Extend = function(b,c){
        return f.call(null,"extend_A",b,c);
    }

    有一个应用场景:

    例如现在有一个方法 根据不同的文件类型进行相应的处理,通过bind 就可以创建出简化版的处理方法
    
    function FileDealFunc(type,url,callback){
        if(type=="txt"){...}
        else if(type=="xml"){...}
        .....
    }
    
    var TxtDealFunc = FileDealFunc.bind(this,"txt");
    //这样使用的时候更方便一些
    
    FileDealFunc("txt",XXURL,func);  //原来
    
    TxtDealFunc(XXURL,func); //现在

    对于旧的版本,可以用以下方式做兼容处理(EcmaScript5中扩展了叫bind的方法(IE6,7,8不支持))

    if (!Function.prototype.bind) {
        Function.prototype.bind = function(obj) {
            var _self = this
                ,args = arguments;
            return function() {
                _self.apply(obj, Array.prototype.slice.call(args, 1));
            }
        }
    }

    不过上面的函数,好像只接受了一个参数。

  • 相关阅读:
    Java Output流写入包装问题
    SpringBoot项目单元测试不经过过滤器问题
    SpringSecurity集成启动报 In the composition of all global method configuration, no annotation support was actually activated 异常
    JWT jti和kid属性的说明
    Maven 排除依赖
    第五章 基因概念的发现
    第三章 孟德尔遗传的拓展
    第二章 孟德尔遗传
    第一章 引言
    GWAS全基因组关联分析
  • 原文地址:https://www.cnblogs.com/charlesblc/p/6071577.html
Copyright © 2011-2022 走看看