【前置知识】
- this
回顾this
- 在全局环境里,
this
始终指向全局对象。 - 在函数内部,
this
的取值取决于函数被调用的对象。
this
是JavaScript里难点之一,因为this
不能在执行期间被赋值,并且在每次函数被调用时 this
的值也可能会不同。
因此 this
的指向不明确,让人诟病!
为了让 this
指向明确,以下方法可以改变 this
指向。
- 使用ES6的箭头函数
- 使用
apply
、call
、bing
- new实例化一个对象
重点讲apply
、call
、 bing
apply
apply() 方法调用一个函数, 其具有一个指定的this值,以及作为一个数组(或类似数组的对象)提供的参数
语法
fun.apply(thisArg, [argsArray])
- thisArg:在 fun 函数运行时指定的 this 值。
- argsArray:一个数组或者类数组的对象
- 如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。
- 如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数。
例子1:
let obj = {
name: '小明'
}
function func(firstName, lastName){
console.log(firstName + ' ' + this.name + ' ' + lastName);
}
func.apply(obj, ['A','B']) //打印出 "A 小明 B"
call()
**call()**
方法使用一个指定的this
值和单独给出的一个或多个参数来调用一个函数。
语法:
function.call(thisArg, arg1, arg2, ...)
- thisArg:在
function
函数运行时使用的this
值。 - arg1, arg2, …:指定的参数列表。
thisArg
的取值有以下4种情况:
- 不传,或者传null,undefined, 函数中的this指向window对象。
- 传递另一个函数的函数名,函数中的this指向这个函数的引用。
- 传递字符串、数值或布尔类型等基础类型,函数中的this指向其对应的包装对象,如 String、Number、Boolean。
- 传递一个对象,函数中的this指向这个对象。
例子2:
简单的 call()
使用
let person = {
name: "bens",
sayHi(p1, p2) {
console.log(p1 + p2 + ":" + this.name)
}
}
//call和apply的唯一区别就是传参时apply是数组的形式.
person.sayHi.call(person, "你", "是")
call() 和 apply() 区别
不同点:
apply
接受可包含多个参数的数组,而call
接受的是包含若干个参数的参数列表。
共同点:
apply
( 同call
)调用一个函数,第一个参数指定this
值。- 定义:应用某一对象的一个方法,用另一个对象替换当前对象。
- 为函数运行时的使用的
this
值,但使用的this
值并不一定是该函数执行时的真正的this
值。 - 在非严格模式下,
null
和undefined
会自动替换成全局对象(浏览器里就是window
),同时值为原始值(数字、字符串、布尔值)的this
指向该原始值的包装对象。 - 直接执行:
这种方式直接function func() {
console.log('linxin');
}
func.call(); // linxin
func()
也没什么区别。
bind()
**bind()**
方法创建一个新的函数,在bind()
被调用时,这个新函数的this
被指定为bind()
的第一个参数,而其余参数将作为新函数的参数,供调用时使用。 ———MDN
语法:
function.bind(thisArg[, arg1[, arg2[, ...]]])
绑定this, 使得this不会被改变, 也可以绑定普通的参数
arg1, arg2, arg3…..:
- 当目标函数被调用时,被预置入绑定函数的参数列表中的参数。
例子3:
function f1(p1, p2) {
console.log(this.name, p1, p2)
}
//f2等价于f1.call({name: "bens"}, "我是第一个参数, 我被绑定了")
let f2 = f1.bind({ name: "bens",}, "我是第一个参数, 我被绑定了")
f2("我是第二个参数, 只需要传我就可以, 其他都被绑定了")
总结
- apply 、 call 、bind 三者都是用来改变函数的this对象的指向的;
- apply 、 call 、bind 三者第一个参数都是this要指向的对象。
- apply 、 call 、bind 三者都可以利用后续参数传参;
- bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用 。
【资料来源】 JavaScript 中 apply 、call 的详解 javaScript 中 call、apply、bind的用法详解 深入浅出 妙用Javascript中apply、call、bind