通过学习call(),apply(),bind()的用法和区别,我们能更好的理解this
及作用域的含义,为后面的编程打下基础。
call()的用法:
调用一个函数,使其具有一个指定的this
值和分别地提供的参数(参数的列表)
参数解释:function.call(thisArg, arg1, arg2, ...)
;
thisArg
:在fun函数运行时指定的this
值*。*需要注意的是,指定的this
值并不一定是该函数执行时真正的this
值,如果这个函数处于non-strict mode,则指定为null
和undefined
的this
值会自动指向全局对象(浏览器中就是window对象),同时值为原始值(数字,字符串,布尔值)的this
会指向该原始值的自动包装对象。
arg1, arg2, ...
:指定的参数列表。
举例说明:
function Animal(type, value) {
this.type = type;
this.value = value;
}
function Dog(type, value) {
Animal.call(this, type, value);
this.name = "二狗子";
this.age = 18
}
var hehe = new Dog("室友", "1");
console.log(hehe.name); //二狗子
console.log(hehe.type); //室友
复制代码
在上述例子中,通过call
改变了Animal
的this
指向Dog
,并且将参数type
,value
传入Animal
中。
apply()的用法
调用一个具有给定this
值的函数,以及作为一个数组(或类似数组对象)提供的参数。
参数解释:func.apply(thisArg, [argsArray])
thisArg
: 可选的。在 func
函数运行时使用的 this
值。请注意,this
可能不是该方法看到的实际值:如果这个函数处于非严格模式下,则指定为 null
或 undefined
时会自动替换为指向全局对象,原始值会被包装。
argsArray
:可选的。一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 func
函数。如果该参数的值为 null
或 undefined
,则表示不需要传入任何参数。
举例说明:
//求数组中的最大值
var arr = [2, 7, 10, 1]
function getMax2(arr) {
return Math.max.apply(null, arr);
//return Math.max.call(null, ...arr);
}
console.log(getMax2(arr)); //10
alert(Math.max(1,4,9,6)); //9
复制代码
在上述例子中,我们可以看出apply
和call
的不同:**接收的参数一个是数组一个是参数列表。**而在Math.max.apply(null, arr)
中apply
会自动将数组转变成参数列表,其等价于Math.max(2,7,10,1)
apply
还多用于构造函数绑定:链接
bind()的用法
创建一个新的函数,在调用时设置this
关键字为提供的值。并在调用新函数时,将给定参数列表作为原函数的参数序列的前若干项。
参数解释: function.bind(thisArg[, arg1[, arg2[, ...]]])
thisArg
:调用绑定函数时作为this
参数传递给目标函数的值。 如果使用new
运算符构造绑定函数,则忽略该值。当使用bind
在setTimeout
中创建一个函数(作为回调提供)时,作为thisArg
传递的任何原始值都将转换为object
。如果bind
函数的参数列表为空,执行作用域的this
将被视为新函数的thisArg
。
arg1, arg2, ...
:当目标函数被调用时,预先添加到绑定函数的参数列表中的参数。
举例说明:
window.value = 3;
var foo = {
value:1
};
function bar() {
console.log(this.value);
}
bar(); // 3
bar.call(foo); //1
//指定函数this绑定为foo, 产生一个新函数,之后再运行的时候,内部的this就是被绑定的对象
var bindFoo = bar.bind(foo);
setTimeout( function() {
bindFoo();
},2000)
// 2秒后打印 1
复制代码
这个例子可以通过对比,很好的理解bind
的运用:
-
bar()
直接调用函数,其中的value
指的是全部变量value = 3
-
bar.call(foo)
这里使用call
立刻改变了bar
中的this
指向为foo
中
var bindFoo = bar.bind(foo);
setTimeout( function() {
bindFoo();
},2000)
复制代码
bind
常用于异步,在setTimeout
中,设置的时间内,bar
的this
保留着指向foo
,所以两秒后打印1,不是3。
通过这个例子,我们了解到call(),apply()
与bind()
的不同之处是bind()
可以为目标函数保留this
的指向,当执行目标函数时,this
会指向设置的作用域。
说明:参数解释来源于MDN