• 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));
            }
        }
    }

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

  • 相关阅读:
    mac安装和启动mongodb
    Promise
    Vue 对象更改检测注意事项
    Vue 改变数组触发视图更新
    MBE风格图标
    为什么vue中的data用return返回
    数据库补充知识之sql编程
    第一阶段:Python开发基础 day45 数据库基础知识之子查询视图的相关操作事务和游标等
    第一阶段:Python开发基础 day44 数据库基础知识之多表查询
    第一阶段:Python开发基础 day43 数据库基础知识之多表操作
  • 原文地址:https://www.cnblogs.com/charlesblc/p/6071577.html
Copyright © 2020-2023  润新知