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()

 

posted @ 2017-12-05 17:56  伊优  阅读(313)  评论(0编辑  收藏  举报