call、applay和bind

            function test(){
                console.log(this)
            }
            test();//打印window
            var t=new test()//打印test(){}

首先我们要明白上面这个this指向问题,普通函数调用,this指向window,而通过new来实例化一个构造函数的对象,则this指向函数。

1.call、apply和bind 的相同点和不同点

相同点:call、apply和bind都是JS函数的公有的内部方法,他们都是重置函数的this,改变函数的执行环节。

不同点:bind是创建一个新的函数,而call和aplay是用来调用函数;call和apply作用一样,只不过call为函数提供的参数是一个个地罗列出来,而apply为函数提供的参数是一个数组。

2.call的用途。

首先,在函数调用的时候,我们都习惯直接调用,比如说function test(){};test();其实这并不是函数调用的本质,本质是test.call();test()只不过是本质的语法糖,它只能调用,而不能改变函数的执行环境。如下所示。

            function test(){
                console.log("hello world");
            }
            //函数的一般调用
            test();
            //函数调用的本质
            test.call()

那么call是如何改变函数的执行环境的?如下所示:

            //这个myName变量相当于给window这个对象添加了一个myName属性
             var myName="yyl"
            function test(){
                //此时的this就是指window
                console.log(this.myName)//打印yyl
            }
            test()
            var obj={myName:"hhh"}
            test.call(obj)//打印hhh

这也就解释了我们之前写的那篇原型中,子函数要想继承父函数需要在子函数中写{Father.call(this)},这个this指向的是Son函数,那么就改变了Father的this指向,将其指向到Son函数中,也就实现了Son函数的实例调用Father的属性。如下所示。

            function Father() {
                this.health = "very good"
            }
            function Son() {
                Father.call(this);
            }
            var son = new Son();
            console.log(son.health)//打印very good

当然,这样写也可以。

            function Father() {
                this.health = "very good"
            }
            function Son() {}
            var son = new Son();
            Father.call(son);
            console.log(son.health)//打印very good

3.apply的用途。

apply除了后面的参数形式与call有区别,其他都一样。比如上面所有用到call的地方都可以用apply来代替。千万不要小看了这个这个参数形式,有些情况下就只能用apply不能用call,比如使用Math.max去获取数组(这个数组有很多元素)的最大值时,若是用call,需要将数组的所有元素陈列出来,而使用apply直接写一个数组就可以。如下:

            var arr=[1,3,2,6,4];
            //1.普通调用方法,是下面这个call方法的语法糖
            console.log(Math.max(1,2,3,6,4))//打印6
            //调用的实质
            console.log(Math.max.call(null,1,2,3,6,4));//打印6
            //使用apply方法
            console.log(Math.max.apply(null,arr));//打印6

4.bind的用途。

直接上代码:

             var myName="yyl";
             function test1(){
                 console.log(this.myName);
             }
             test1();//打印yyl
             var obj={myName:"hhh"}
             var test2=test1.bind(obj);
             test2();//打印hhh

可以看出bind与call的唯一区别就是call直接改变函数test的指向,而bind是生成了一个新函数test2,该函数改变了指向。

猜你喜欢

转载自blog.csdn.net/yangyalun/article/details/108883475