JavaScript中this详解

98 阅读1分钟

this指向

<script>
    this 谁调用 this就指向谁 (es6箭头函数之前)
    
    1.     function test() {}
           test() // 当前this指向window
           window.test() // 当前this指向window
           // 全局中所有的方法都挂载到了window上,test() 等价于 window.test()
           
    2.     let mpobj = {
                name:"安红",
                test:function(){
                    console.log(this) // 当前this指向obj
                }
           } 
           mpobj.test() // 谁调用this就指向谁

    3.     setTimeout(function(){
                console.log(this) // window setTimeout是window下面的方法
           })
           
    4.     // 事件绑定的this
           btn.onclick = function() {
               console.log(this) // 当前this指向btn
           }
           
   总结:
   1.     全局中定义的函数,this全部指向window
   2.     对象中定义的的函数,this指向当前调用的对象
   3.     setTimeout setinterval this指向window
   4.     事件绑定的this,指向绑定事件的节点对象
</script>

改变this指向(强行掰弯)

<script>
    call apply bind
    
    let mpobj = {
        name:"mpobj",
        getName:function() {
            console.log(this.name)
        }
    }
    
    let mpobj2 = {
        name:"mpobj2",
        getName:function() {
            console.log(this.name)
        }
    }
    
    // call apply 改变this并执行
    
    // 此时mpobj下面的getName方法中的this就指向mpobj2 
    // mpobj.getName.call(mpobj2)  打印mpobj2
    mpobj.getName.call(mpobj2) 
    
    // 此时mpobj下面的getName方法中的this就指向mpobj2 
    // mpobj.getName.apply(mpobj2)  打印mpobj2
    mpobj.getName.apply(mpobj2) 
    
    // 传递参数
    let mpobj = {
        name:"mpobj",
        // a,b,c 就是传过来的参数
        getName:function(a,b,c) {
            console.log(this.name)
        }
    }
    
    // call 传参需要单个传值 支持多个参数
    mpobj.getName.call(mpobj2,1,2,3)
    
    // apply 传参需要传一个数组 值支持两个参数 第二个参数是一个数组
    mpobj.getName.call(mpobj2,[1,2,3])
    
    // bind 改变this,不会自动执行函数
    let fun = mpobj.getName.bind(mpobj2) 
    // bind传参
    let fun = mpobj.getName.bind(mpobj2,1,2,3) 
    // 需要手动调用fun执行函数
    fun()
    
    // bind场景使用
    function handleClick () {
        console.log(this)
    }
    btn.onclick = handleClick.bind(window)
    // 比如手动点击btn想要执行handleClick方法,并且想改变函数内部的this,此时用call或apply就不合适了,因为call和apply会立即执行,在一些不需要执行的地方,并且还要改变this执行的地方,就可以使用this了
    
   总结:
   1.     call改变this并执行,参数需要单个传递
   2.     apply改变this并执行,参数需要传递数组
   3.     bind改变this指向不执行,需要手动调用执行,参数需要单个传递
</script>

箭头函数中的this

<script>
    btn.onclick = function() {
        setTimeout(function(){
            // 此时的this是window,setTimeout是通过window来调用的
            console.log(this)
        },1000)
    }
    
    btn.onclick = function() {
        setTimeout(()=>{
            // 此时的this是btn,箭头函数的this是父级作用域的,父级的this是谁,当前的this就是谁
            console.log(this)
        },1000)
    }
   总结:
   1.    箭头函数的this是父级作用域的,父级的this是谁,当前的this就是谁
</script>