关于JavaScript 中call、apply、bind的区别
首先,三个函数都是可以用来调用函数,且允许改变函数中 this 的指向
Function.call()
1.语法:
xxx.call(thisArg, arg1, arg2, …, argN)
2.参数:
thisArg:在调用 func 时要使用的 this 值。
arg1, …, argN(可选参数):用来传递函数的实际参数。
3.使用实例
当我们在调用函数的时候,函数内的this默认是指向window这个对象
// 创建一个名为hello函数
function hello(){
console.log(this)
}
// 调用hello
hello()
控制台输出:
创建一个名为hello函数,然后调用,打开浏览器控制台,可以看到输出的对象确实为window,那为什么是window呢,其实this默认指向的是函数的调用者,至于为什么是window,其实是调用函数的时候因为省略了window,完整的写法是:
// 创建一个名为hello函数
function hello(){
console.log(this)
}
// 完整的写法是window.hello(),所以函数内的this指向的是window
window.hello()
那为什么要改变this的指向呢,改变this之后可以让函数的使用更加灵活,方便,举个栗子:
// 创建一个对象
const person = {
name: '大帅哥',
age: '18'
}
function hello(){
console.log('我的对象是一个'+ this.name + ',今年刚满' + this.age + '岁')
}
// 改变this的指向,这样在函数内就可以直接通过this直接调用指向对象的属性
hello.call(person)
控制台输出:
接着就是关于参数与返回值的问题
// 创建一个对象
const person = {
name: '大帅哥',
age: '18'
}
function hello(x, y){
console.log('我的对象是一个'+ this.name + ',今年刚满' + this.age + '岁')
return x + y;
}
// 改变this的指向
const res = hello.call(person, 1, 2)
console.log('x + y = ' + res)
在call方法指向参数后面的参数会传给函数,返回值也会返回回去
控制台输出:
Function.apply()
apply()的用法其实跟call()差不多,只不过在传参的时候有所不同
1.语法:
xxx.apply(thisArg, argsArray)
2.参数
thisArg:在调用函数时要使用的 this 值。
argsArray(可选参数):一个数组对象,也就是我们常见的 [1, 2, 3] 的这种形式,用于指定调用函数时的参数,或者如果不需要向函数提供参数,则为 null 或 undefined。
3.使用实例
使用跟call()基本一致,只不过第二个参数为数组,this指向person这个对象,值得一提的是,第一个参数也可以给null,表示不指向任何对象,也就是原来指向的是什么就还是什么。
// 创建一个对象
const person = {
name: '大帅哥',
age: '18'
}
const arr = [1, 2];
function sum(x, y){
console.log('我的对象是一个'+ this.name + ',今年刚满' + this.age + '岁')
console.log(x + y)
}
// 相当于 => sum.apply(person, [1, 2])
sum.apply(person, arr)
控制台输出:
值得一提的是,当第一个参数为null的时候,表示原本指向的是什么对象this就是指向什么对象
const arr = [1, 2];
function sum(x, y){
console.log(this) // 输出 window
console.log(x + y)
}
// 相当于 => sum.apply(person, [1, 2])
sum.apply(null, arr)
再举个例子:
const numbers = [5, 6, 2, 3, 7];
// before
const before = Math.max(5, 6, 2, 3, 7);
console.log("不使用apply的方式,before = " + before) // 控制台输出:7
// after,此时就可以将数组直接传入
const after = Math.max.apply(null, numbers);
console.log("使用apply的方式,after = " + after) // 控制台输出:7
// 当然,也可以用数组展开的方式
const number = Math.max(...numbers)
console.log("使用展开的方式,number = " + number) // 控制台输出:7
Function.bind()
最后关于bind()的使用,不知道各位大帅哥大漂亮有没有发现前面两个方式都是在直接调用函数的时候去使用,举个例子,我调用 sum.apply(null, arr) 之后,会直接执行这个函数,但是有时候往往我只需要重新指向一下this的指向,我并不需要马上调用,那么就可以用到bind()。
1.语法:
xxx.bind(thisArg, arg1, arg2, …, argN)
2.参数
thisArg:在调用函数时要使用的 this 值。
argsArray(可选参数):用来传递函数的实际参数。
3.使用实例
// 创建一个对象
const person = {
name: '大帅哥',
age: '18'
}
function hello(x, y){
console.log('我的对象是一个'+ this.name + ',今年刚满' + this.age + '岁')
console.log('x + y = ' + (x + y))
return x + y;
}
const bind = hello.bind(person, 1, 2)
bind()
控制台输出:
就此可以看出三者之间的区别
总结一下:
call、apply、bind三个函数都可以用来改变函数内this的指向。
1.call()的第一个参数传this要指向的对象,第二个参数以后是以逗号分隔的形式进行传参。
2.apply()的第一个参数传this要指向的对象,第二个参数以后是数组的形式进行传参。
3.bind()的第一个参数传this要指向的对象,第二个参数以后是以逗号分隔的形式进行传参,但是与前两者的区别是不会主动去调用函数,只是单纯的绑定this要指向的对象!
PS:各位佬,幸会!如果有什么不对的地方,欢迎各位佬在评论区或私信纠正,还请各位多多指教,创作不易,如果该文章有能帮助你的地方,还请给点个赞,谢谢!!!!!!