this延伸,关于call、apply 和 bind的理解
在JavaScript里面,函数不仅仅是一行可执行代码,它们也是对象。这里call、apply、bind是三个非常重要的方法,它们关乎开发者精确控制函数内部的this上下文。
详细this讲解:揭秘 JavaScript 中的 this:谁在调用我?深入理解
.call()
- 通过传递参数的方式,
call()允许指定函数执行时的this上下文 - 当
call()被调用时,它会立即执行所引用的函数。 - 这意味着一旦
call()方法被执行,目标函数就会紧接着被调用,而不需要等待任何异步操作或事件循环的下一个周期。
示例:
var obj = {
name: "Cherry",
func1: function() {
console.log(this.name)
},
func2: function() {
setTimeout(function() {
this.func1()
}.call(obj), 5000)
}
}
这里的打印并没有执行setTimeout定时器机制,而是立即执行了。
.bind()
bind不会立即执行原函数,而是返回一个新的函数。- 可以提前绑定一些参数,即所谓的“部分应用”。
- 新函数的
this不会因为后续调用方式的不同而改变。
示例:
var obj = {
name: "Cherry",
func1: function() {
console.log(this.name)
},
func2: function() {
setTimeout(function() {
this.func1()
}.bind(obj), 5000)
}
}
这里实现了延时执行的场景:
因为bind() 创建并返回一个新函数,其 this 永久绑定到指定对象,并在 setTimeout 的延迟后执行;而 call() 立即执行函数并临时绑定 this,不适用于延迟执行的场景。
.bind()与.call()的区别
var obj1 = {
name: "Cherry",
}
function func1() {
console.log(this.name)
}
func1.call(obj)
func1.bind(obj)
.apply()
用途:apply 方法与 call 类似,与 call 一样,apply 也会立即执行函数。但它接受的是一个参数数组而不是一系列参数,所有参数都包含在一个数组中传递给目标函数。
示例:
var obj = {
func:function(a,b){
console.log(a+b)
}
}
var a = obj.func
// 将 `a.fn` 的值复制给变量 `b`,如果 `a.fn` 是一个对象或函数,
// 那么 `b` 和 `a.fn` 将引用同一个对象或函数实例
console.log(a.apply(a,[1,2]))
结果:
apply()、call()之间传递参数区别
- apply(thisArg,[arg1,arg2,..])
- thisArg参数,进行函数内部this的指向值。
- [arg1,arg2,..] 参数做为数组或类数组对象,直接解析数组里面的每个元素,依次传递给目标函数。
var obj = {
func:function(a,arr){
console.log(a)
console.log(arr)
}
}
var a = obj.func
// 将 `a.fn` 的值复制给变量 `b`,如果 `a.fn` 是一个对象或函数,
// 那么 `b` 和 `a.fn` 将引用同一个对象或函数实例
console.log(a.apply(a,[1,[1,2]]))
- call(thisArg, arg1, arg2, ...)
- thisArg参数,进行函数内部this的指向值。
- arg1,arg2,... 参数一个个的,按顺序传递给目标函数。
var obj = {
func:function(a,b){
console.log(a+b)
}
}
var a = obj.func
// 将 `a.fn` 的值复制给变量 `b`,如果 `a.fn` 是一个对象或函数,
// 那么 `b` 和 `a.fn` 将引用同一个对象或函数实例。
console.log(a.call(a,1,2))
console.log(a.call(a,[1,2]))
打印:1,2undefined
- [1,2]作为一个整体传递给a,b没有传递值,定义为undefined。
- 运用了连接运算符,a [1,2] + b undefined -> [1,2].tostring = '1,2' + String(undefined) = 'undefined' -> 1,2undefined
总结
在 JavaScript 中,call、apply 和 bind 方法都用于控制函数执行时的 this 上下文,但它们的行为有所不同:call 和 apply 立即执行函数并分别以参数列表和参数数组的形式传递参数;而 bind 返回一个新函数,其 this 永久绑定到指定对象,适用于需要延迟执行或部分应用参数的场景。