【前置知识】
- 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
