简述对call()、apply()、bind()的理解和区别
1、call()、apply()、bind() 都是用来重定义 this 这个对象的!
- call 、bind 、 apply 这三个函数的第一个参数都是 this 的指向对象,第二个参数差别就来了:
- call 的参数是直接放进去的,第二第三第 n 个参数全都用逗号分隔,直接放到后面 obj.myFun.call(db,'成都', ... ,'string' )。
- apply 的所有参数都必须放在一个数组里面传进去 obj.myFun.apply(db,['成都', ..., 'string' ])。
- bind 除了返回是函数以外,它 的参数和 call 一样。
- 当然,三者的参数不限定是 string 类型,允许是各种类型,包括函数 、 object 等等!
2、call()
-
call() 方法调用一个函数, 其具有一个指定的 this值和分别地提供的参数(参数的列表)。 第一个参数:在 fun 函数运行时指定的 this 值;如果指定了 null 或者 undefined 则内部 this 指向 window,后面的参数:指定的参数列表
-
var fn = function(arg1, arg2) { }; fn.call(this, arg1, arg2); var numbers = [5, 458 , 120 , -215 ]; var maxInNumbers = Math.max.call(Math,5, 458 , 120 , -215); //获取数组中的最大值458
3、apply()
-
apply()方法调用一个函数, 其具有一个指定的
this
值,以及作为一个数组(或类似数组的对象)提供的参数。apply()
与call()
非常相似,不同之处在于提供参数的方式。apply()
使用参数数组而不是一组参数列表。 -
var fn = function(arg1, arg2) { }; fn.apply(this, [arg1, arg2]) var numbers = [5, 458 , 120 , -215 ]; //umber 本身没有 max 方法,但是 Math 有,我们就可以借助 call 或者 apply 使用其方法。 var maxInNumbers = Math.max.apply(Math, numbers), //获取数组中的最大值458
4、bind()
-
bind() 函数会创建一个新函数(称为绑定函数),新函数与被调函数(绑定函数的目标函数)具有相同的函数体(在 ECMAScript 5 规范中内置的call属性)。
当目标函数被调用时 this 值绑定到 bind() 的第一个参数,该参数不能被重写。绑定函数被调用时,bind() 也接受预设的参数提供给原函数。
一个绑定函数也能使用new操作符创建对象:这种行为就像把原函数当成构造器。提供的 this 值被忽略,同时调用时的参数被提供给模拟函数。 -
//在常见的单体模式中,通常我们会使用 _this , that , self 等保存 this ,这样我们可以在改变了上下文之后继续引用到它 var fn = { bar : 1, eventBind: function(){ var _this = this; $('.someClass').on('click',function(event) { console.log(_this.bar); //1 }); } } //当然使用 bind() 可以更加优雅的解决这个问题: var fn = { bar : 1, eventBind: function(){ $('.someClass').on('click',function(event) { /* Act on the event */ console.log(this.bar); //1 }.bind(this)); } } //创建了一个新的函数 func,当使用 bind() 创建一个绑定函数之后,它被执行的时候,它的 this 会被设置成 fn , 而不是像我们调用 bar() 时的全局作用域。 var bar = function(){ console.log(this.a); } var fn = { a:3 } bar(); // undefined var func = bar.bind(fn); func(); // 3