js中关于this的指向问题

194 阅读1分钟

关于this的总结

  1. 沿着作用域向上找最近的一个function(不是箭头函数),看这个function最终怎样执行的
  2. this的指向取决所属function的调用方式,而不是定义
  3. function调用一般分为一下几种情况
  1. 作为函数调用,即: foo()
 function foo () {
     //指向全局对象(globalThis),注意严格模下是undefined 
     console.log(this) // window
 }
  1. 作为方法的调用,即 foo.bar() / foo.bar.fn() / foo['bar']() / fo[0]()
    function bar () {
        console.log(this)
    }
    const foo = {bar:bar}
    foo.bar() // foo
   
    const obj = {
        bar:{
            fn:bar
        }
    }
    obj.bar.fn() // bar
    
    const arr = [bar]
    arr[0]() // arr
    
    //总结:指向最终调用这个方法的对象 

  1. 作为构造函数调用,即 new Foo()
     class Foo {
        constructor () {
            console.log(this)
        }
     }
     new Foo() 
     // 指向一个新对象Foo{}
  1. 特殊调用,即 foo.call() / foo.apply() / foo.bind()
    function foo(){
        console.log(this)
    }
    const obj = {}
    foo.call(obj) //obj
    foo.call(1) //Number
    //指向参数指定成员
  1. 找不到所属的function,就是全局对象
    console.log(this)
  1. 箭头函数中的this指向离他最近作用域中的this,他会一层层往上查找,直到找到含有this
   function fn () {
       const foo = ()=>{
           console.log(this)
       }
       foo()
   }
   const obj = {fn:fn}
   obj.fn() //obj
   fn() //window
   
  1. 事件绑定中的this,一般就是绑定事件的DOM元素
    const elm = document.createElement('div')
    elm.addEventListener('click',function (){
        console.log(this) //elm
    })

练习看看下面this指向谁

    var length = 10
    function fn () {
        console.log(this.length)
    }
    var obj = {
        length:5,
        method (fn) {
            fn()            //?
            arguments[0]()  //?
        }
    }
    obj.method(fn,1,2,3)
    
    var x = 2
    var obj = {x:3}
     obj.fn = (function () {
            this.x *= ++x
            return function (y){
                this.x *= (++x + y)
                console.log(x)
            }
       })()
    var fn = obj.fn
    obj.fn(5) //?
    fn(4) //?

上述答案依次是 10 4 7 84