这是一个常见的基础面试题,下面我们举个例子来看下他们三个的写法,三者的区别自然就出来了。
var name = '张三'
var age = 18
var obj = {
name: '李四',
trueAge: this.age,
fun: function (a, b) {
console.log(
`名字是:${this.name},年龄是:${this.age},真实姓名:${a},真实年纪:${b}`
)
},
}
var myObj = {
name: '王五',
age: 23,
}
obj.trueAge // 18
obj.fun() // 名字是:李四,年龄是:undefined,真实姓名:undefined,真实年纪:undefined
可以看到obj中没有age。
下面我们来改变this的指向:
obj.fun.call(myObj) // 名字是:王五,年龄是:23,真实姓名:undefined,真实年纪:undefined
obj.fun.apply(myObj) // 名字是:王五,年龄是:23,真实姓名:undefined,真实年纪:undefined
obj.fun.bind(myObj)() // 名字是:王五,年龄是:23,真实姓名:undefined,真实年纪:undefined
可以看出来三者改变this指向时,bind 返回的是一个新的函数,必须调用它才会被执行。
下面我们来看传参数的区别:
obj.fun.call(myObj, '王哈尼', 25) // 名字是:王五,年龄是:23,真实姓名:王哈尼,真实年纪:25
obj.fun.apply(myObj,['王哈尼',25]) // 名字是:王五,年龄是:23,真实姓名:王哈尼,真实年纪:25
obj.fun.bind(myObj,'王哈尼',25)() // 名字是:王五,年龄是:23,真实姓名:王哈尼,真实年纪:25
传参数的区别,call()和bind()参数之间用逗号隔开,而apply()参数为数组格式。
顺便提一下,单纯的调用这三个方法不加参数,this指向的是window。
obj.fun.call()
obj.fun.apply()
obj.fun.bind()()
obj.fun.call(window)
obj.fun.apply(window)
obj.fun.bind(window)()
// 输出结果都是 名字是:张三,年龄是:18,真实姓名:undefined,真实年纪:undefined