关于-this指向的理解

this 的不同应用场景,如何取值

  • 作为普通函数被调用

  • 使用 call apply bind

  • 作为对象方法被调用

  • 在class方法中调用

  • 箭头函数 (找上级作用域)

this 取什么值是在函数执行的时候确认的,不是在函数定义的时候确认的
/* 
    this 指向  window  因为   他当做执行函数 执行函数会直接确认this指向
*/
/*
     this 指向 当前对象  因为   箭头函数 作为回调函数来使用  只有当函数被调用的    时候才会触发  this指向
*/ 
const pepole = {
    await(){
        setTimeout(function (){
            console.log(this);   
        }) 
        setTimeout(() =>{
            console.log(this);  
        })
    }
}

call, apply, bind都是改变函数执行的上下文,说的直白点就是改变了函数this的指向。不同的是:call和apply改变了函数的this,并且执行了该函数,而bind是改变了函数的this,并返回一个函数,但不执行该函数。

call 内部实现原理

call() 方法调用一个函数, 其具有一个指定的 this 值和分别地提供的参数(参数的列表)。

注意:该方法的作用和 apply() 方法类似,只有一个区别,就是 call() 方法接受的是若干个参数的列表,而 apply() 方法接受的是一个包含多个参数的数组。

语法:

fun.call(thisArg[, arg1[, arg2[, ...]]])

参数:

  • thisArg

    • 在 fun 函数运行时指定的 this 值
    • 如果指定了 null 或者 undefined 则内部 this 指向 window
  • arg1, arg2, ...

    • 指定的参数列表
    Function.prototype.call = function(thisArg, args) {
      // this指向调用call的对象
      if (typeof this !== 'function') { // 调用call的若不是函数则报错
          throw new TypeError('Error')
      }
      thisArg = thisArg || window
      thisArg.fn = this   // 将调用call函数的对象添加到thisArg的属性中
      const result = thisArg.fn(...[...arguments].slice(1)) // 执行该属性
      delete thisArg.fn   // 删除该属性
      return result
    }

apply 内部实现原理

apply() 方法调用一个函数, 其具有一个指定的 this 值,以及作为一个数组(或类似数组的对象)提供的参数。

注意:该方法的作用和 call() 方法类似,只有一个区别,就是 call() 方法接受的是若干个参数的列表,而 apply() 方法接受的是一个包含多个参数的数组。

语法:

fun.apply(thisArg, [argsArray])

参数:

  • thisArg
  • argsArray

apply()call() 非常相似,不同之处在于提供参数的方式。
apply() 使用参数数组而不是一组参数列表。例如:

fun.apply(this, ['eat', 'bananas'])
Function.prototype.apply = function(thisArg, args) {
    if (typeof this !== 'function') { 
        throw new TypeError('Error')
    }
    thisArg = thisArg || window
    thisArg.fn = this
    let result
    if(args) {
        result = thisArg.fn(...args)
    } else {
        result = thisArg.fn()
    }
    delete thisArg.fn
    return result
}

bind 内部实现原理

bind后的函数会返回一个函数,而这个函数也可能被用来实例化

bind方法后面有一对空格,所以得出结论bind返回的是一个函数必须调用才会执行 bind({x:20})()

语法:

fun.bind(thisArg[, arg1[, arg2[, ...]]])

返回值:返回由指定的this值和初始化参数改造的原函数的拷贝。

Function.prototype.bind = function(thisArg) {
    if(typeof this !== 'function'){
        throw new TypeError(this + 'must be a function');
    }
    // 存储函数本身
    const _this  = this;
    // 去除thisArg的其他参数 转成数组
    const args = [...arguments].slice(1)
    // 返回一个函数
    const bound = function() {
        // 可能返回了一个构造函数,我们可以 new F(),所以需要判断
        if (this instanceof bound) {
            return new _this(...args, ...arguments)
        }
        // apply修改this指向,把两个函数的参数合并传给thisArg函数,并执行thisArg函数,返回执行结果
        return _this.apply(thisArg, args.concat(...arguments))
    }
   return bound
}

对 bind this 指向的 一些总结

bind this 指向问题 ,就是 谁调用,在哪里调用,this指向 就会在哪里 发送, 并且this 就会指向 他。

简单来说 就是 this 指向 是 根据自由变量来决定的 ,自由变量在他被调用 ,被使用的 时候 他会在 他的作用域来进行查找 这个当前 使用的 变量 ,然后根据 他 需要访问的变量 ,然后 来 使他这个 变量值进行 改变,this 指向的是在 哪里 进行调用 ,就会在哪个作用域中进行调用。

自由变量的查找,是在函数定义的地方,向上级作用域查找,不是在执行的地方查找!

this指向的是当前对象。如果在全局范围内使用 this ,则指代当前页面 window 如果在函数中使用this, 则this指代什么是根据当前函数是什么对象上调用。我们可以callapplybind 改变函数中 this 的 具体指向
本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!