持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第5天,点击查看活动详情
函数this的三种指向(面试)
环境对象 this: 谁'调用'我 , 我指向谁(与函数的声明方式无关,与调用方式有关)
1.普通函数 : 函数名() this指向window
2.构造函数: new 函数名() 指向 new 创建的实例对象
3.对象方法 : 对象名.方法名() 指向对象
function fn(){
console.log( this )
}
//普通函数 : window
fn()
//构造函数 : new创建实例对象
new fn()
let obj = {
name:'张三',
eat:fn
}
//对象方法 : obj对象
obj.eat()
补充: 定时器里面的this永远指向 window, 用上下文调用也无法修改
函数的上下文调用
语法: 函数名.call(修改的this,参数一,参数二...... )
会直接调用函数,并修改函数的this指向
function fn(a, b) {
console.log(this) // {name:'阿洋'}
console.log(a + b)
}
// 函数名.call(修改的this,参数一,参数二....)
// 会直接调用函数,并修改函数的this指向
fn.call({
name: '阿洋'
}, 10, 20)
应用场景: 万能数据检测
Object.prototype.toString.call(数据)
用object原型对象的方法,但需要改变this,改为检测的数据
typeof 数据: 可以检测数据类型 , 但null 与 array 无法检测其类型 结果都是"object"
apply()调用函数
语法: 函数.apply(修改后的this,数组或伪数组)
会直接调用函数,并修改this指向,另外apply会自动帮你遍历数组,然后按照顺序逐一传参
function fn(a, b) {
console.log(this) // {name: '哈哈'}
console.log(a + b)
}
fn.apply({
name: '哈哈'
}, [20, 30])
bind()调用函数
语法: 函数.bind(修改后的this)
1.不会立即执行函数,而是得到一个修改this之后的新函数
2.一般用于不会立即执行的函数, 如定时器
3.bind 也可以传参,但一般不传,因为传参会绑定所传参数,且不能覆盖
function fn(a, b) {
console.log(a + b)
console.log(this)
}
let newFn = fn.bind({
name: '王少辉'
})
newFn(2, 5)
三者的区别(面试):
call 和 apply 和 bind 三者区别
相同点 : 作用一致,修改函数this指向
不同点 : 传参方式不同 : call是按照顺序传参, apply是数组/伪数组传参
执行机制不同 : call和apply会立即执行函数,而bind不会立即执行而是得到修改this的新函数