一、call/apply/bind
改变函数执行时,里面this指向对象
call
call()
方法里面第一个参数时this指向对象,第二个参数是函数执行时要传入的参数,只能一个一个的传入
const obj = {
a: '李狗蛋',
b: '王翠花',
}
function Hello (s) {
console.log(this)
console.log('a=' + this.a + 'b=' + this.b + 'c=' + s)
}
Hello()
Hello.call(obj, c)
// 打印结果
window {...}
a=1b=2c=undefined
{a: "李狗蛋", b: "王翠花"}
a=李狗蛋b=王翠花c=3
正常情况下,Hello
函数是全局对象window
上挂载的一个函数,函数执行时,this应该指向调用它的对象window
,但是通过call
方法传入了obj
对象,让函数里面的this变成了obj
对象
浏览器环境或者非严格模式下,如果传入null
或者undefined
,则this将会指向全局对象window
,如果是其他环境,如node,this则指向global
// 注意声明变量时,一定要用var,如果用const,let,则会显示undefined
// 通过var,相当于在window全局对象上声明了a和b两个属性
var a = 1
var b = 2
const c = 3
function Hello (s) {
console.log(this)
console.log('a=' + this.a + 'b=' + this.b + 'c=' + s)
}
Hello.call(null, c)
// 打印结果
window{...}
a=undefinedb=2c=3
如果是在严格模式下,this将不会发生改变,传入什么就是什么
// 严格模式
'use strict'
var a = 1
var b = 2
const c = 3
const obj = {
a: '李狗蛋',
b: '王翠花',
}
function Hello (s) {
console.log(this)
console.log('a=' + this.a + 'b=' + this.b + 'c=' + s)
}
Hello.call(null, c)
// 打印结果
null
报错:Cannot read property 'a' of null at Hello
apply
aplly
方法是用来改变函数执行时this指向对象,方法有两个参数,第一个参数是this指向的对象,第二个参数是函数执行时要传入的参数,必须是一个数组
var a = 1
var b = 2
const c = 3
const obj = {
a: '李狗蛋',
b: '王翠花',
}
function Hello (s) {
console.log(this)
console.log('a=' + this.a + 'b=' + this.b + 'c=' + s)
}
Hello(c)
Hello.apply(obj, [c])
// 打印结果
window {...}
a=1b=2c=3
{a: "李狗蛋", b: "王翠花"}
a=李狗蛋b=王翠花c=3
可以看到同call
一样,正常情况下,Hello
函数是全局对象window
上挂载的一个函数,函数执行时,this应该指向调用它的对象window
,但是通过apply
方法传入了obj
对象,让函数里面的this变成了obj
对象
浏览器环境或者非严格模式下,如果thisArg
传入null
或者undefined
,则this将会指向全局对象window
,如果是其他环境,如node,this则指向global
var a = 1
var b = 2
const c = 3
const obj = {
a: '李狗蛋',
b: '王翠花',
}
function Hello (s) {
console.log(this)
console.log('a=' + this.a + 'b=' + this.b + 'c=' + s)
}
Hello.apply(undefined, [c])
// 打印结果
window {...}
a=1b=2c=3
如果是在严格模式下,thisArg将不会发生改变,传入什么就是什么
'use strict'
var a = 1
var b = 2
const c = 3
const obj = {
a: '李狗蛋',
b: '王翠花',
}
function Hello (s) {
console.log(this)
console.log('a=' + this.a + 'b=' + this.b + 'c=' + s)
}
Hello.apply(undefined, [c])
// 打印结果
undefined
报错:Cannot read property 'a' of undefined at Hello
bind
bind
也是用来改变thisArg
指向对象的,第一个参数是函数执行时的thisArg
指向对象,第二个对象是传入到函数里面的参数,这个方法同call
差不多
Tips
Tips
Tips
1、bind
是返回一个函数,而不是像call
,apply
一样立即调用,而是需要手动去调用触发函数
2、bind
传入的参数并不等同于原函数传入的参数,而是在原函数的参数前面作为新增参数,添加进去,原来参数多余的就清除掉
var a = 1
var b = 2
const c = 3
const obj = {
a: '李狗蛋',
b: '王翠花',
}
function Hello (s, d, k) {
console.log(this)
console.log('a=' + this.a + 'b=' + this.b + 'c=' + s + 'd=' + d + 'e=' + k)
}
Hello()
Hello.bind(obj, c)(7, 8, 9)
// 打印结果
window {...}
a=1b=2c=undefinedd=undefinede=undefined
{a: "李狗蛋", b: "王翠花"}
a=李狗蛋b=王翠花c=3d=7e=8 // 9没了,因为只有三个形参位置,bind加了一个,最后的9就要清除掉
浏览器环境或者非严格模式下,如果thisArg
传入null
或者undefined
,则this将会指向全局对象window
,如果是其他环境,如node,this则指向global
var a = 1
var b = 2
const c = 3
const obj = {
a: '李狗蛋',
b: '王翠花',
}
function Hello (s, d, k) {
console.log(this)
console.log('a=' + this.a + 'b=' + this.b + 'c=' + s + 'd=' + d + 'e=' + k)
}
Hello.bind(undefined, c)(7, 8, 9)
// 打印结果
window {...}
a=1b=2c=3d=7e=8
如果是在严格模式下,thisArg将不会发生改变,传入什么就是什么
'use strict'
var a = 1
var b = 2
const c = 3
const obj = {
a: '李狗蛋',
b: '王翠花',
}
function Hello (s, d, k) {
console.log(this)
console.log('a=' + this.a + 'b=' + this.b + 'c=' + s + 'd=' + d + 'e=' + k)
}
Hello.bind(undefined, c)(7, 8, 9)
// 打印结果
undefined
报错:Cannot read property 'a' of undefined at Hello