this指向问题

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>this指向常见问题</title>
</head>
<body>
    <script>
        // 默认绑定
        // 1. 严格模式下
        var a = 10
        console.log(this.a) // 10
        function func(){
            // "use strict" // 在严格模式下,函数体内的this指向undefined
            var a = 12
            console.log("func",this.a) // 10 -- this为window,this.a 为全局window下的a
        }
        func()
        
        function foo(){
            console.log("use strict")
        }
        (function(){
            "use strict"
            foo() // use strict -- 这里调用foo仍然是window , 若是this.foo() -- 的this指向undefined 找不到foo方法
        })()

        // 2. 全局下用let const声明的变量不会绑定在window上
        // 3. 普通函数的嵌套
        var a = 12
        function func2(){
            var a = 13
            function inner(){
                console.log(this.a) //12
            }
            inner()
        }
        func2()
        // 隐式绑定 -- this指向最后调用的对象
        var obj = {
            name: "hh",
            foo: function(){
                console.log(this.name)
            }            
        }
        obj.foo() //"hh" -- this指向obj
        // 隐式绑定的隐式丢失
        // 隐式丢失1. 使用另外的变量给函数起别名
        var name = "window name"
        var foo = obj.foo
        foo() // window name
        // 隐式丢失2. 把函数作为参数进行传递 -- 作为参数传递的函数里的this指向为window
        function foo2(foo){
            foo()
        }
        foo2(foo) // window name: foo中的this指向window
        // ⚠️ 作为参数来传递函数造成的函数隐式丢失,作为参数的函数的this指向window,与包裹它的函数的this指向无关
        var obj2 = {
            name: "obj2 name",
            foo2
        }
        obj2.foo2(obj.foo) // window name
        // 另外 settimeout中回调函数的this,也属于这种隐式丢失,this指向window

        // 显示绑定 -- 通过call apply bind方法来改变this指向
        // 函数返回的函数中的this指向为最后调用它的对象,与外层函数无关
        var a = 11
        function foo3(){
            console.log(this.a)
            return function(){
                console.log(this.a)
            }
        }
        var obj = {a: 22}
        foo3.call(obj)()// 22  11 -- foo3的this指向obj,但是调用匿名函数的是window -- (匿名函数的this指向永远指向window)

        // forEach map filter这些方法 的第二个参数可以用来绑定this

        // new绑定 -- this指向new创建的对象(举例略)

        // 箭头函数绑定 -- 箭头函数中的this由外层作用域决定,指向函数定义时的this而非执行时的this
        // 对象字面量 & 箭头函数
        var name = "window-name"
        var obj = {
            name: "obj-name",
            func1: () =>{
                console.log(this.name)
            },
            func2: function(){
                console.log(this.name)
                return ()=>{
                    console.log(this.name)
                }
            },
            func3: () => {
                console.log(this.name)
                return ()=>{
                    console.log(this.name)
                }
            }
        }
        obj.func1() // window-name : 方法func1定义时的作用域为全局作用域,obj不是作用域,作用域仅分为全局作用域和局部作用域
        obj.func2()() // obj-name obj-name : func2箭头函数在定义时,处于函数作用域,因此return的箭头函数中的this指向obj
        obj.func3()() // window-name  window-name: 两个箭头函数定义时的this执行都是全局window
        // 构造函数 & 箭头函数
        function Person(name){
            this.name = name
            this.func = ()=>{
                console.log(this.name)
            }
        }
        var person = new Person("person-name")
        person.func() // person-name : 箭头函数定义时的this指向person

        // 箭头函数与call结合 -- 箭头函数无法通过call apply bind方法直接进行this指向的修改,但是可以修改作用域的this指向来间接修改
        // 易错题
        var name = 'window'
        function Person (name) {
        this.name = name
        this.obj = {
            name: 'obj',
            foo1: function () {
            return function () {
                console.log(this.name)
            }
            },
            foo2: function () {
            return () => {
                console.log(this.name)
            }
            }
        }
        }
        var person1 = new Person('person1')
        var person2 = new Person('person2')

        person1.obj.foo2()() // obj -- 箭头函数的作用域是foo2的作用域,foo2在this.obj内,this.name 执行obj
        person1.obj.foo2().call(person2) //obj
    </script>
</body>
</html>

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值