call和apply,bind的区别

195 阅读2分钟

函数的this指向

函数的this指向:谁调用“我”,我就指向谁。

  • 普通函数:函数名()     this  ===>  window
  • 构造函数:new 函数名()  this  ===>  new创建实例
  • 对象方法:对象名.方法()  this  ===>  对象 默认情况下,函数内部的this是固定的,无法动态修改。如果想要动态修改函数this指向,需要使用函数上下文调用。
  • 函数上下文引用:函数的作用域

函数上下文调用——动态修改this指向

call

语法:函数名.call(修改的this,参数1,参数2....)

    //创建一个函数
    const fn = function (age, height) {
            console.log(this)
            console.log(`年龄:${age},身高:${height}cm`)
        }
    //直接调用,this指向window
    fn(20, 175)  // window  年龄:23,身高:167cm
    const data = {
            name: "张三"
        }
    //使用call修改this指向
    fn.call(data, 20, 175) //{name: '张三'}  年龄:20, 身高:175cm
    //修改成功,fn的this指向了data这个对象

apply

语法:函数名.apply(修改的this, 数组/伪数组 )

    //创建一个函数
    const fn = function (age, height) {
            console.log(this)
            console.log(`年龄:${age},身高:${height}cm`)
        }
    //直接调用,this指向window
    
    fn(20, 175)  // window  年龄:23,身高:167cm
    
    const data = {
            name: "张三"
        }
    const arr = [20, 175]
    //使用apply修改this指向
    // apply底层会自动遍历数组,然后按照顺序逐一传参
    
    fn.apply(data, arr) //{name: '张三'}  年龄:20, 身高:175cm
    //修改成功,fn的this指向了data这个对象

bind

函数名.call(修改的this,参数1,参数2…………)

    //创建一个函数
    const fn = function (age, height) {
            console.log(this)
            console.log(`年龄:${age},身高:${height}cm`)
        }
    //直接调用,this指向window
    
    fn(20, 175)  // window  年龄:23,身高:167cm
    
    const data = {
            name: "张三"
        }
    //使用bind修改this指向
    // bind不会立即执行函数,而是返回一个修改this之后的新函数
    let newFn = fn.bind(data, 20, 175) 
    //调用newFn
    newFn()  //{name: '张三'}  年龄:20, 身高:175cm
    //修改成功,fn的this指向了data这个对象
    //也可以写成下面的格式,结果是一样的
    //let newFn = fn.bind(data) //修改this指向,创建了一个新的函数(不调用不执行)
    //newFn(20,175) //在调用函数的时候传参

总结

共同点
  • 1.都是用来改变函数的this对象的指向的。
  • 2.第一个参数都是this要指向的对象。
  • 3.都可以利用后续参数传参。
不同点
  • 1.传参方式不同 : call是单个单个传参, apply是数组/伪数组传参。
  • 2.执行机制不同 : call和apply立即执行函数, bind不会立即执行,而是返回一个修改this之后的新函数。