• call、apply、bind的用法


    数组追加

          //用apply拼接
                var arr1=[12,'name:foo',2048];
                var arr2=['Joe','Hello'];
                Array.prototype.push.apply(arr1,arr2);
                console.log(arr1);//(5) [12, "name:foo", 2048, "Joe", "Hello"]
                //用call拼接
                var arr1=[12,'name:foo',2048];
                var arr2=['Joe','Hello'];
                Array.prototype.push.call(arr1,arr2);
                console.log(arr1);//(4) [12, "name:foo", 2048, Array(2)]  Array(2) ["Joe", "Hello"]是arr2只占一位,然后在第三位下面又分2位

    获取数组中的最大值和最小值

          //对比call和apply (参数明确时用call)
                var numbers=[25,456,86,-45];
                var maxNum=Math.max.apply(Math,numbers)//传入的是一个数组
                console.log(maxNum);//456
                var numbers=[25,456,86,-45];
                var maxNum=Math.max.call(Math,25,456,86,-45)//传入的一个个参数
                console.log(maxNum);//456

    验证是否是数组(前提是toString()方法没有被重写过)

          var arr=[1,2,3,4,5];
                function isArray(obj){
                     return  Object.prototype.toString.call(obj) === '[object Array]' ;
                }
                isArray(arr);
                console.log(isArray(arr))//true

    apply的用法

           function log(msg)  // 常规写法
                {
                    console.log(msg);
                }
                log(1);//1
                log(1,2);//1 1

     用apply的方法

           function log()
                {
                    console.log.apply(console,arguments);
                }
                log(1);//1
                log(1,2);//1 2

    bind的用法

               //常规写法
                var
    foo = { bar : 1, eventBind: function(){ console.log(this) var _this = this; $('.someClass').on('click',function(event) { // Act on the event console.log(_this.bar); //1 }); } } foo.eventBind();          
             //bind的写法
            var
    foo = { bar : 1, eventBind: function(){ $('.someClass').on('click',function(event) { // Act on the event console.log(this.bar); //1 }.bind(this)); } }   foo.eventBind();

    bind() 创建了一个函数,当这个click事件绑定在被调用的时候,它的 this 关键词会被设置成被传入的值(这里指调用bind()时传入的参数)。因此,这里我们传入想要的上下文 this(其实就是 foo ),到 bind() 函数中。
    然后,当回调函数被执行的时候, this 便指向 foo 对象。

    案例

        var bar = function(){
                        console.log(this.x);
                    }
                var foo = {
                    x:3
                }
                var sed = {
                    x:4
                }
                var func = bar.bind(foo).bind(sed);
                    func(); //3  此时输出的为3
                    
                var fiv = {
                    x:5
                }
                var func = bar.bind(foo).bind(sed).bind(fiv); 
                func(); //3 //此时输出的为3

    在Javascript中,多次 bind() 是无效的。更深层次的原因,bind() 的实现,相当于使用函数在内部包了一个 call / apply,第二次 bind() 相当于再包住第一次 bind() ,故第二次以后的 bind 是无法生效的。
    bind()返回的内容

           var obj = {
                        x: 81,
                    };
                    
                var foo = {
                        getX: function() {
                            return this.x;
                        }
                }
                var a = foo.getX.bind(obj); //81
                console.log(a()); //81
    //          console.log(foo.getX.bind(obj)()); //81  call和apply是立即执行,而bind返回的是函数

    call 方法

                //使用call方法调用匿名函数
                var peoples=[
                    {name:'Jane',age:16},
                    {name:'Maria',age:15}
                ]
                for(var i=0;i<peoples.length;i++){
                    (function(i){
                        this.print=function(){
                            console.log(i+"----" +this.name+"---"+this.age);
                        }
                        this.print();
                    }).call(peoples[i],i)
                }
          //使用call方法调用父构造函数
                function Product(name,price){
                    this.name=name;
                    this.price=price
                        if(price < 0){
                            throw RangeError('Connot create product'+this.name+'with a negative price');                
                        }
                    }    
                    function Food(name,price){
                        Product.call(this,name,price);
                        this.category='food';            
                    }
                    var cheese = new Food('feta', 5);
                    console.log(cheese);//Food {name: "feta", price: 5, category: "food"}

    简单用法

              function cat(){
                    }
                    cat.prototype={
                         food:"fish",
                         say:function(){
                               alert("I love "+this.food);
                         }
                    }             
                    var blackCat = new cat;
                    blackCat.say();
                    var whiteDog = {food:"bone"};
                    console.log(whiteDog);
                    blackCat.say.apply(whiteDog);

    总结:

    apply 、 call 、bind 三者都是用来改变函数的this对象的指向的;
    apply 、 call 、bind 三者第一个参数都是this要指向的对象,也就是想指定的上下文;
    apply 、 call 、bind 三者都可以利用后续参数传参;

    apply 、 call 会立刻执行,而bind的回调函数

    apply传入的是数组apply(this,[argu1,argu2,argu3,argu4]),call是call(this,argu1,argu2,argu3,argu4),如果传入的参数个数是已知的,可以用call方法。如果个数未知,用apply方法。

    -------------------------------------------------------------------------------------------------2018-06-04-----------------------------------------------------------------------------------------------------------------------

            var obj={
                    name:"Jack",
                    getName:function(age,gender){
                            console.log(this.name)
                            console.log(age)
                            console.log(gender)
                        }
                    }
                   obj.getName(12,'男')//obj自己调用
                   
                var People={
                    name:"Jane"
                }
                obj.getName.call(People,15,'男') //call
                obj.getName.apply(People,[15,'男']) //apply
                var a = obj.getName.bind(People,15,'男') // bind返回的是一个回调函数
                a()

     当bind和call复用的时候

                     function fn(name){
                                    this.name=name
                                    console.log(this.name)
                                }
                                var a = fn.bind.call(fn,{},'Jack'); //第一个参数是bind要调用的函数,第二个参数是call函数执行函数执行时的上下文,依次是传入函数的参数
                                a()
                                //等同于
                                var orgBindFun = Function.prototype.bind;
                                var b = orgBindFun.call(fn,null,'Jack')
                                b()
  • 相关阅读:
    Go语言的性能测试对比
    学习笔记
    使用TCPDump分析Redis的Pipeline比Multi更快的原因
    基于Redis/Memcached的高并发秒杀设计
    这些 .Net and Core 相关的开源项目,你都知道吗?(持续更新中...)
    《.Net 的冰与火之歌》寄雁传书,你必须知道的C#参数知识大盘点
    分享自己的超轻量级高性能ORM数据访问框架Deft
    Expression2Sql的一些语法更新
    介绍一个可以将Expression表达式树解析成Transact-SQL的项目Expression2Sql
    记一次随机字符串生成算法的随机概率与性能的提升
  • 原文地址:https://www.cnblogs.com/xumqfaith/p/7988557.html
Copyright © 2020-2023  润新知