this指向

时间:2021-09-06
本文章向大家介绍this指向,主要包括this指向使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

 普通函数执行

  • 自执行函数this指向window
  • 如果普通函数执行,前面没有"."this指向window,如果前面有“.”的话,“.”前面是谁this就是谁
    function fn() {
        console.log(this)
    }
    let obj
    = { name: 'zhangshan', fn: fn } fn() // window obj.fn() // obj

构造函数执行

  • 构造函数执行,函数中的this指向的是当前类的实例
    function fn() { 
       console.log(this)     // fn
    }
    let f = new fn()

事件绑定方法

  • 给元素的某个事件行为绑定方法,事件触发,方法执行些时方法中的this一般指向当前对象元素。
  • DOM0
    btn.onclick = function() {
      console.log(this)   // btn  
    }
  • DOM2
    btn.addEventListener('click',function() {
        console.log(this)    // btn
    }, false)
    btn.attachEvent('click',function() {
       // IE8浏览器中的DOM2事件绑定
        console.log(this)    // window
    }, false)

箭头函数

  • 箭头函数中没有自身的this,所用到this都是其上下文中的this
    let  obj = {
      fn: ()=> {
          consloe.log(this)    // window     
      }  
    }    
  • 箭头函数没有的东西
    • prototype,所以不能被new函数
    • 没有arguments实参集合(可以基于...args剩余运算获取)
      let obj = {
        fn:(...arg) => {
          console.log(args)
        }  
      } 

可以改变this的指向的方法

    • call方法执行的时候,会把[function]执行,并且把函数中的THIS指向为[context],并且把params1,params2…等参数值分别传递给函数。
      var obj = {};
      
      var f = function () {
        return this;
      };
      
      f() === window        // true
      f.call(obj) === obj.  // true
    • call方法的参数,应该是一个对象。如果参数为空、nullundefined,则默认传入全局对象。
      var n = 123;
      var obj = { n: 456 };
      
      function a() {
        console.log(this.n);
      }
      
      a.call() // 123
      a.call(null) // 123
      a.call(undefined) // 123
      a.call(window) // 123
      a.call(obj) // 456
    • call可以传人多个参数
      fn.call(obj, arg1, arg2, arg3, ....)
      call的第一个参数就是this所要指向的那个对象,后面的参数则是函数调用时所需的参数
      function add(a, b) {
        reurn a + b  
      }
      fn.call(this, 1, 2) // 3
    • call方法的一个应用是调用对象的原生方法

      var obj = {};
      obj.hasOwnProperty('toString') // false
      
      // 覆盖掉继承的 hasOwnProperty 方法
      obj.hasOwnProperty = function () {
        return true;
      };
      obj.hasOwnProperty('toString') // true
      
      Object.prototype.hasOwnProperty.call(obj, 'toString') // false
    • call方法实现原理
      Function.prototype.myCall = function(context = window, ...args) {
        // context如果没传是window
        // 但如果传了,且并非是对象,怎么办?比如:String,Boolean等,但不包含Array、Function等
        context = context instanceof Object ? context : {}
        // 在上下文中执行fn方法,保证执行环境是context
        context.fn = this
        const result = context.fn(...args)
        // 原生call是不会污染context的,所以这里要删除掉
        delete context.fn
        // 返回执行结果
        return result
      }
  • apply
    • apply方法的作用与call方法类似,也是改变this指向,然后再调用该函数。唯一的区别就是,它接收一个数组作为函数执行时的参数
      func.apply(thisValue, [arg1, arg2, ...])
    • apply的一些应用
      • 找出数组最大元素
        let arr = [10, 2, 4, 15, 9];
        Math.max.apply(null, arr)
      • 将数组的空元素变为undefined
        Array.apply(null, ['a', ,'b'])
        // [ 'a', undefined, 'b' ]
      • 转换类似数组的对象
        Array.prototype.slice.apply({0: 1, length: 1}) // [1]
        Array.prototype.slice.apply({0: 1}) // []
        Array.prototype.slice.apply({0: 1, length: 2}) // [1, undefined]
        Array.prototype.slice.apply({length: 1}) // [undefined]
    • apply实现原理
      Function.prototype.myApply = function(context=window, arg) {
        context.fn = this;
      let result = context.fn(arg)
      delete context.fn return result; }
  • bind
    • bind()方法用于将函数体内的this绑定到某个对象,然后返回一个新函数。
    • call/apply都是把当前函数立即执行,并且改变函数中的this指向的,而bind是一个预处理的思想
    • 基于bind只是预先把函数中的this指向[context],把params这些参数值预先存储起来,但是此时函数并没有被执行
    • bind的实现原理
      Function.prototype.myBind = function(context = window, ...args) {
        const fn = this;
        return function() {
          return fn.apple(context, [...args, ...arguments])
       }
      }

原文地址:https://www.cnblogs.com/lucky1010/p/15234783.html