zoukankan      html  css  js  c++  java
  • this指向的问题以及改变方法

    this指向问题最核心的一句话:

    哪个对象调用函数,函数里面的this就指向哪个对象

    理解起来是有点抽象

    下面是一些列子

    1、普通函数调用

    2、对象函数调用

    3、构造函数调用

    4、apply、call调用

    5、箭头函数调用

    一、普通函数调用

    在非严格模式下,this的指向都是window

    下面需要注意let、var不同写法的区别

    先介绍下let、 var,let是块级作用域变量,写在函数中则只在函数内部有效。var申明的变量要不是全局的,要么就是函数级别的,不是块级的

    这里用代码简单介绍下let、var

    都是let的情况下

    <script>
            let fn = function() {
                let name = 'tom'
                if (true) {
                    let name = 'pig'
                    console.log(name);
                }
                console.log(name);
            }
            fn()
        </script>
    

    image-20210617210613027

    先使用let后使用var

    <script>
            let fn = function() {
                let name = 'tom'
                if (true) {
                    var name = 'pig'
                    console.log(name);
                }
                console.log(name);
            }
            fn()
        </script>
    

    image-20210617210756205

    会发现报错,因为var相当于函数级作用域,相当于一个函数作用域中有两个n的变量,var作用于整个fn,和let冲突了,let不能重复的声明,already been declared=已经被声明。

    先var 后let的情况

    <script>
            let fn = function() {
                 var name = 'tom'
                if (true) {
                    let name = 'pig'
                    console.log(name);
                }
                console.log(name);
            }
            fn()
        </script>
    

    image-20210617211119625

    这里没发现报错因为先声明var再声明let是可以的

    上面可以简单的对var let有个理解,方便理解下面的知识

    1、使用let

     <script>
            let name = "tom"
    
            function fn() {
                console.log(this.name); //undefind
            }
            fn();
        </script>
    

    这里打印出来的是undefined

    2、使用var

     <script>
            var name = "tom"
    
            function fn() {
                console.log(this.name); //tom
            }
            fn();
        </script>
    

    这里打印出来的是tom

    区别就是上面描述的

    3、使用window

     <script>
            window.name = "tom"
    
            function fn() {
                console.log(this.name); //tom
            }
            fn();
        </script>
    

    打印出来的是tom

    二、对象函数调用

    简单的理解就是哪个函数调用,this就指向哪里

    <script>
            let name = "tom"
            let obj = {
                id: 121,
                fn: function() {
                    console.log(this.name);
                    console.log(this.id);
                }
            }
            obj.fn()
        </script>
    

    image-20210617211644290

    这里obj调用了函数,所以this指向指向了obj,obj中只有id没有那么

    这里会出现b赋值给a然后a调用,注意this指向不要搞混

     <script>
            let obj1 = {
                name: "tom"
            }
            let obj2 = {
                name: "pig",
                fn: function() {
                    console.log(this.name);
    
                }
            }
            obj1.fn = obj2.fn
            obj1.fn()
        </script>
    

    image-20210617212139077

    再次声明:哪个函数调用this就指向哪里

    三、构造函数调用

     <script>
            let fn = function() {
                this.name = "tom"
            }
            let fn1 = new fn()
            console.log(fn1.name);
    
            let fn2 = new fn()
    
            fn2.name = "pig"
            console.log(fn2.name);
        </script>
    
    

    这里可以看到this指向

    image-20210617214730491

    这里需要注意return的出现

    <script>
            let fn = function() {
                this.name = "tom"
                return {
                    username: 'age'
                }
            }
            let fn1 = new fn()
            console.log(fn1);
            console.log(fn1.name);
        </script>
    

    image-20210617214935628

    这里发现return中的this指向指向的直接指向这个对象,而不是函数

    四、apply和call、bind

    上面介绍了this在函数中的指向问题,在现实中我们可以改变this的指向,比如apply、call、bind

    apply

    用法:改变函数中的this指向。

    xxx.apply(对象名,数组) 就是将xxx函数中的this指向指向对象名,数组中的元素依次与元素的参数对应

    function fn(a, b) {
                console.log(this);
                console.log(a + b);
            }
            fn(1, 2)
            var obj = {
                name: 'tom'
            }
            fn.apply(obj, [3, 4])
    

    image-20210618215533051

    call

    用法:改变函数中的this指向问题,和apply的区别是第二个参数不为数组

    xxx.call(对象名,参数1,参数2,参数3.......) 就是将xxx函数中的this指向指向对象名,参数中的元素依次与元素的参数对应

    <script>
            function fn(a, b) {
                console.log(this);
                console.log(a + b);
            }
            fn(1, 2)
            var obj = {
                name: 'tom'
            }
            fn.call(obj, 3, 4)
        </script>
    

    image-20210618215842176

    bind

    用法:改变函数中的this指向问题,和call写法一样,不同的地方是bind返回的是一个函数,所以我们在调用的时候在进行传参

    xxx.bind(对象)(参数1,参数2......)

     <script>
            function fn(a, b) {
                console.log(this);
                console.log(a + b);
            }
            fn(1, 2)
            var obj = {
                name: 'tom'
            }
            fn.bind(obj)(3, 4)
        </script>
    

    image-20210618220443791

    五、箭头函数调用

    ES6中提供的箭头函数,箭头函数中没有this,箭头函数中的this是继承外部函数的this。

    <script>
            let obj = {
                name: 'tom',
                fn: function() {
                    setTimeout(function() {
                        console.log(this.name)
                    })
                }
            }
            obj.fn()
        </script>
    

    这里的到的this.name为undefined,因为普通函数中的this指向的是window对象,这里window中并没有定义name,所以为空。

    <script>
            let obj = {
                name: 'tom',
                fn: function() {
                    setTimeout(() => {
                        console.log(this.name)
                    })
                }
            }
            obj.fn()
        </script>
    

    这里使用箭头函数,在定时器中找不到this指向会向上级查找,所以是tom

    image-20210618223314055

  • 相关阅读:
    很牛逼的android真机调试,手机、平板、电视都可
    设置TextView文字居中
    设置文本编辑器的按回车时触发的事件
    windows搭建virtualbox虚拟机安装的android环境
    Android EditText不弹出输入法焦点问题的总结
    MAVEN 的常用命令
    PuTTY_0.67.0.0工具链接linux
    CentOS6.8安装
    互亿无线短信验证码
    MYSQL: sql中某一个字段内容为用逗号分割的字符串转换成多条数据
  • 原文地址:https://www.cnblogs.com/AFBF/p/14901480.html
Copyright © 2011-2022 走看看