this的三种指向和修改this的方法

127 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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的新函数