# JavaScript 中 call()、apply()、bind() 的用法
先看两个例子
# 例子1
var name = "小布",age = 18
var obj = {
name: "小红",
objAge: this.age,
myFun: function(){
console.log(`姓名:${this.name},年龄:${this.age}`)
}
}
console.log(obj.objAge) //18
console.log(obj.myFun()) //姓名:小红,年龄:undefined
# 例子2
var name = "小布"
function showName() {
console.log(this.name)
}
showName() //小布
**结论:**例子1中的 objAge中的 this 指向 window,因此拿到的值 是 18. myFun 中的 this 指向的是 obj对象,因此 拿到 name 是 小红, 但是 对象中并没有age 因此 打印的值为 undefined。例2中 函数一样的,this指向的是 window。
**存在问题:**由于函数中this指向不是很明确,有时候需要改变this指向,因此出现了call()、apply()、bind()三个方法。这三个方法的出现就是改变this指向的。
如:
var name = "小布", age = 18
var obj = {
name: "小红",
objAge: this.age,
myFun: function(){
console.log(`姓名:${this.name},年龄:${this.age}`)
}
}
var otherObj = {
name: "张三",
age: "99"
}
console.log(obj.myFun()) //姓名:小红,年龄:undefined
console.log(obj.myFun.call(otherObj)) //姓名:张三,年龄:99
console.log(obj.myFun.apply(otherObj)) //姓名:张三,年龄:99
console.log(obj.myFun.bind(otherObj)()) //姓名:张三,年龄:99
call,apply,bind 三个方法除了bind方法后面需要多个 () 外,其余没有区别,且返回结果都一致
结论: bind返回的是一个新的函数,因此使用bind时需要加个()调用。且call,apply,bind的第一个参数为 this的指向对象。
# 对比call、apply、bind传参情况下的区别
var name = "小布", age = 18
var obj = {
name: "小红",
objAge: this.age,
myFun: function(from,to) {
console.log(`姓名:${this.name} 年龄:${this.age},来自${from}去往${to}`)
}
}
var otherObj = {
name: "李四",
age: 88
}
console.log(obj.myFun("厦门","北京")) //姓名:小红 年龄:undefined,来自厦门去往北京
console.log(obj.myFun.call(otherObj,"厦门","北京")) //姓名:李四 年龄:88,来自厦门去往北京
console.log(obj.myFun.call(otherObj,["厦门","北京"])) //姓名:李四 年龄:88,来自厦门,北京去往undefined
console.log(obj.myFun.call(otherObj,["厦门","北京"],"漳州")) //姓名:李四 年龄:88,来自厦门,北京去往漳州
console.log(obj.myFun.apply(otherObj,["厦门","北京"])) //姓名:李四 年龄:88,来自厦门去往北京
console.log(obj.myFun.bind(otherObj,"厦门","北京")()) //姓名:李四 年龄:88,来自厦门去往北京
console.log(obj.myFun.bind(otherObj,["厦门","北京"])()) //姓名:李四 年龄:88,来自厦门,北京去往undefined
console.log(obj.myFun.bind(otherObj,["厦门","北京"],"漳州")()) //姓名:李四 年龄:88,来自厦门,北京去往漳州
从上面的结果不难看出
call、apply、bind这三个函数的第一个参数都是this的指向对象,主要区别就是第二个参数
call 参数是直接放进去的,第二个第三个第n个参数全都用逗号分隔,直接放到后面obj.myFun.call(otherObj,"厦门",..., "string")
apply 的所有参数必须放在一个数组里面传进去,obj.myFun.apply(otherObj,["厦门",..., "string"])
bind除了返回是函数以外,他的参数和call一样。
当然,三者的参数不限定是 string 类型,允许是各种类型,包括函数 、 object 等等!