JavaScript中call、apply、bind三者的区别

call和apply的区别

在ECMAScript 规范中给所有的函数都定义了两个方法call()和apply(),它们俩的作用是相同的,唯一的不同是在传参的形式上有所差别:

首先来看:apply()

apply()方法有两个参数,其中第一个参数是函数上下文的对象,第二个参数是函数参数所组成的数组 apply(obj,[A, B])

<script>
        var obj = { name: 'xiaobai'}
        function myfunc (firstname, lastname){
            console.log(firstname + ' ' + this.name + ' ' + lastname)
        }
        myfunc.apply(obj, ['A','B'])  //A xiaobai B
 </script>

可以发现,函数 myfunc 中的 this 指向的是对象 obj ,参数A,B是放在一个数组中传入到函数 myfunc ,数组元素分别对应函数 myfunc 参数的列表元素。

call()

call()方法的第一个参数也是作为函数上下文的对象,但是第二个参数传入的是一个参数列表,不再是一个单一的数组

        var obj = { name: 'xiaobai'}
        function myfunc (firstname, lastname){
            console.log(firstname + ' ' + this.name + ' ' + lastname)
        }
        myfunc.call(obj, 'C','D')  //C xiaobai D

对比 apply 可以发现,call方法中C、D是作为单独的参数传给函数myfunc 的,不再是放在单个数组中传参。

至于什么时候用两个方法:如果你的参数本来就是一个数组毫无疑问用apply,如果参数比较散乱、相互之间没什么太大的联系就选择call方法

call、apply的用法

1.改变this的指向
		var obj = {name : 'yueyan'}
        function myfunc (){
            console.log(this.name)
        }
        myfunc.call(obj)

如果不适用call方法,this 指向的是Windows对象,这个该例中把obj作为参数传给了myfunc 函数,此时反函数里面的this 指向了 obj 对象。此处的 myfunc 相当于

        function myfunc (){
            console.log(obj.name)
        }
2.借用别的对象方法
        var person1 = function (){
            this.name = 'qiuqiu';
        }
        var person2 = function (){
            this.getname = function (){
                console.log(this.name)
            }
            person1.call(this)
        }
        var person = new person2();
        person.getname();  //qiuqiu

从上面代码可以发现,person2 实例化出来的对象 person 通过 getname 方法拿到了 person1 中的 name。在 person2 中,person1.call(this) 的作用就是使用person1 对象代替 this 对象,那么 person2 就有了 person1 中的所有属性和方法了,相当于 person2 继承了 person1 的属性和方法。

说白了还是用改变了 this 的指向~~~

call 和 bind 的区别

bind()ES5中扩展的方法,不兼容低版本IE,和 call 类似,第一个参数是作为函数上下文的对象,第二个参数是个列表,可以接收多个参数。

区别(两点):

1.bind返回值是函数
        var obj = {
            name: 'linxin'
        }
        function func() {
            console.log(this.name);
        }
        var myfunc = func.bind(obj);  //此处的myfunc是个函数
        //去掉bind改为:var myfunc = func(obj); myfunc();此时报错,
        //报错原因是myfunc不是个函数Uncaught TypeError: myfunc is not a function
        myfunc();

bind 方法不会立即执行,而是返回一个改变了 this 后的函数,原函数 func 中的 this 并没有改变,依旧指向全局对象window。

2.参数的使用
		function func(a, b, c) {
            console.log(a, b, c)
        }
        var myfunc = func.bind(null, 'qiuqiu')

        func('A', 'B', 'C')  //A B C
        myfunc('A', 'B', 'C')  //qiuqiu A B
        myfunc('B', 'C')  //qiuqiu B C
        myfunc('C')  //qiuqiu C undefined
        func(null, 'qiuqiu')  //null "qiuqiu" undefined
        func.call(null, 'qiuqiu')  //qiuqiu undefined undefined

call 方法传参是从第二个参数开始所有后面的参数作为func 的实参传进去,myfunc 方法的实参则是在bind 中参数的基础上在往后排。(就是说使用bind 方法后,不管myfunc 方法传进去的参数有多少个,它实际上传进去的参数总是在 bind 的参数基础上,紧跟在bind参数的后面)
~~ ~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值