zoukankan      html  css  js  c++  java
  • 突然顿悟的Javascript中的this

      一直对Javascript中的this都有一种似是而非的感觉,今天突然感觉豁然开朗,特此记录一下。

    咱们先看个栗子:

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title>this的使用</title>
            <script type="text/javascript">
                var Car,tesla;
                Car=function  () {
                    this.start=function(){
                        console.log('car started');
                    };
                    this.turnKye=function () {
                        var carKey=document.getElementById('car_key');
                        carKey.onclick=function () {
                        this.start();    
                        };
                    }
                    return this;
                }
                
                tesla=new Car();
                tesla.turnKye();
            </script>
        </head>
        <body>
          <input type="button" id="car_key" value="test" />
            
        </body>
    </html>

          咋一看这段代码没有什么问题,但是由于对于this的错误理解最终导致错误的结果。我们在元素car_key上面绑定了click事件,认为在car的类中嵌套绑定click事件就可以让这个dom元素访问car的this上下文。这种方式看起来很合理,但是不幸的是它并不工作。

    在Javascript中,this关键字总是指向正执行的作用域的所有者。

      请大家仔细揣摩上面那句话。正如我们所知,函数调用会产生新的作用域,一点onclick事件被触发,this就指向了dom元素而不是Car的类。

      那我们怎么做才会让它能正常工作呢?我们通常会把this赋值给一个局部的自由变量(比如that,_this,self,me等,这个在许多的框架里面都有体现)来避开作用域带来的问题。这里使用局部变量来重写之前的方法:

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title>this的使用</title>
            
        </head>
        <body>
          <input type="button" id="car_key" value="test" />
            <script type="text/javascript">
                var Car,tesla;
                Car=function  () {
                    this.start=function(){
                        console.log('car started');
                    };
                    this.turnKye=function () {
                        var that=this;
                        var carKey=document.getElementById('car_key');
                        
                        carKey.onclick=function () {
                          that.start();    
                        };
                    }
                    return this;
                }
                
                tesla=new Car();
                tesla.turnKye();
            </script>
        </body>
    </html>

      由于that是一个自由变量,onclick事件的出发并不会引起它的重新定义。

       如果你熟悉ES6的话可以使用胖箭头符号,这更简洁和更容易理解,如下:

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title>this的使用</title>
            
        </head>
        <body>
          <input type="button" id="car_key" value="test" />
            <script type="text/javascript">
                var Car,tesla;
                Car=function  () {
                    this.start=function(){
                        console.log('car started');
                    };
                    this.turnKye=function () {
                        //var that=this;
                        var carKey=document.getElementById('car_key');
                        
                        //carKey.onclick=function () {
                         // that.start();    
                        //};
                        carKey.onclick=()=>this.start();
                    }
                    return this;
                }
                
                tesla=new Car();
                tesla.turnKye();
            </script>
        </body>
    </html>

    当然我们也可以使用绑定函数的方法来解决这个问题:如下

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title>this的使用</title>
            
        </head>
        <body>
          <input type="button" id="car_key" value="test" />
            <script type="text/javascript">
                var Car,tesla;
                Car=function  () {
                    this.start=function(){
                        console.log('car started');
                    };
                    
                    var click=function(){
                        this.start();    
                    }
                    this.turnKye=function () {
                        //var that=this;
                        var carKey=document.getElementById('car_key');
                        
                        carKey.onclick=click.bind(this);
                    
                    }
                    return this;
                }
                
                tesla=new Car();
                tesla.turnKye();
            </script>
        </body>
    </html>

    其实这些在学习React的时候,绑定事件的时候遇到的坑,那时候只知道这么写,不知道怎么回事,今天突然感觉豁然开朗。希望对大家有所帮助。

  • 相关阅读:
    86. Partition List
    328. Odd Even Linked List
    19. Remove Nth Node From End of List(移除倒数第N的结点, 快慢指针)
    24. Swap Nodes in Pairs
    2. Add Two Numbers(2个链表相加)
    92. Reverse Linked List II(链表部分反转)
    109. Convert Sorted List to Binary Search Tree
    138. Copy List with Random Pointer
    为Unity的新版ugui的Prefab生成预览图
    ArcEngine生成矩形缓冲区
  • 原文地址:https://www.cnblogs.com/smiler/p/5610056.html
Copyright © 2011-2022 走看看