• this容易混淆的示例


    【注】this 永远不会混乱,混乱的是我们而已。

    /*
    this永远指向当前函数的主人。

    this混乱:
    1、添加了定时器/延时器
    2、事件绑定
    【注】函数如果发生了赋值,this就混乱了。
    */

    示例1和示例2是在事件绑定时出现this混乱的现象

    示例1

    目的:点击页面上的按钮时也 能弹出 10

     1 <!DOCTYPE html>
     2 <html lang="en">
     3     <head>
     4         <meta charset="UTF-8">
     5         <title>Document</title>
     6         <script>
     7             /*
     8                 this永远指向当前函数的主人。
     9 
    10                 this混乱:
    11                 1、添加了定时器/延时器
    12                 2、事件绑定
    13                 【注】函数如果发生了赋值,this就混乱了。
    14             */
    15             function Aaa(){
    16                 this.a = 10;
    17 
    18                 //事件绑定 函数的主人换了
    19                 document.getElementById('btn1').onclick = this.show;
    20             }
    21 
    22             /*在function Aaa的this指向的肯等是 Aaa 的主人, 既 对象a1
    23             所以
    24                 document.getElementById('btn1').onclick = this.show;就等价于
    25                 document.getElementById('btn1').onclick = a1.show; a1.show是对象
    26                 a1的方法。所以又等价于:
    27                 document.getElementById('btn1').onclick = function(){alert(this.a);};
    28                 到此时问题就来了,那么上面这段代码里的this就不是指向对象a1了,此时它还
    29                 是指向函数的主人,但是这个主人就变成了 点击事件的btn1对象了。
    30                 所以当我们点击页面上的按钮时会显示 undefined。
    31              */
    32 
    33             Aaa.prototype.show = function(){
    34                 alert(this.a);
    35             }
    36 
    37             /*var a1 = new Aaa();
    38             alert(a1.a);
    39             a1.show();*/
    40 
    41             window.onload = function(){
    42                 var a1 = new Aaa();//通过调用Aaa函数创建了a1对象
    43                 alert(a1.a);//10
    44                 a1.show();//10
    45             }
    46 
    47         </script>
    48     </head>
    49     <body>
    50         <button id = "btn1">按钮</button>
    51     </body>
    52 </html>
    View Code

    浏览器效果:

     可以看出点击页面按钮时没有弹出10,既出现了this混乱,混乱的原因已经写在代码中

    下面我们来看解决的方案:

     1 <!DOCTYPE html>
     2 <html lang="en">
     3     <head>
     4         <meta charset="UTF-8">
     5         <title>Document</title>
     6         <script>
     7             /*
     8                 this永远指向当前函数的主人。
     9 
    10                 this混乱:
    11                 1、添加了定时器/延时器
    12                 2、事件绑定
    13                 【注】函数如果发生了赋值,this就混乱了。
    14             */
    15             function Aaa(){
    16                 this.a = 10;
    17 
    18                 var _this = this;
    19 
    20                 //事件绑定 函数的主人换了
    21                 document.getElementById('btn1').onclick = function(){
    22                     _this.show();
    23                 };
    24             }
    25 
    26             /*通过变量_this来记录函数function Aaa(){}的this既a1,然后在绑定的点击事件函数
    27             里用_this来调用对象a1的show方法,这样就避免了点击事件里的this指向点击事件对象了。
    28             document.getElementById('btn1').onclick = function(){ _this.show()};就等价于
    29             document.getElementById('btn1').onclick = function(){ a1.show()};,这样就避免了
    30             this混乱了。
    31             */
    32 
    33 
    34             Aaa.prototype.show = function(){
    35                 alert(this.a);
    36             }
    37 
    38             /*var a1 = new Aaa();
    39             alert(a1.a);
    40             a1.show();*/
    41 
    42             window.onload = function(){
    43                 var a1 = new Aaa();
    44                 alert(a1.a);//10
    45                 a1.show();//10
    46 
    47                 //点击页面按钮是也可以正常调用 对象a1的show方法 ,结果:10
    48             }
    49 
    50         </script>
    51     </head>
    52     <body>
    53         <button id = "btn1">按钮</button>
    54     </body>
    55 </html>
    View Code

    效果:

     问题解决。

    我们再来看一下在定时器或者延时器中,出现的现象:

    示例3:

     1 <!DOCTYPE html>
     2 <html lang="en">
     3     <head>
     4         <meta charset="UTF-8">
     5         <title>Document</title>
     6         <script>
     7             //给对象b1添加属性
     8             function Bbb(){//此函数里this的主人为对象b1,不多说
     9                 this.b = 20;
    10 
    11                 //传参 == 赋值
    12                 setTimeout(this.show, 4000);
    13             }
    14 
    15 
    16             //给对象b1添加方法
    17             Bbb.prototype.show = function(){//此函数里this的主人为对象b1,不多说
    18                 alert(this);
    19             }
    20 
    21             var b1 = new Bbb();//通过调用函数Bbb的方式创建对象b1
    22             alert(b1.b);//20
    23             b1.show();//[object Object] 说明是对象 b1
    24 
    25             /*
    26                 上面的延时器过了4s后弹出的 是[object Window],可能有人认为4s后会弹出
    27                 [object Object]。为什么会出现这中现象呢。因为延时器的格式为
    28                 setTimeout(函数名或匿名函数(这里是参数),延时毫秒数)。
    29                 因为传参=赋值。
    30                 因为
    31                 setTimeout(this.show, 4000);
    32                 在函数Bbb里,所以这里面的this都指向b1,
    33                 所以就等价于
    34                 setTimeout(b1.show, 4000);
    35                 因为b1.show又等于函数function(){alert(this);}
    36                 所以等价于
    37                 setTimeout(function(){alert(this);}, 4000);
    38                 到此步骤,this就发生变化了,因为延时器setTimeout是系统调用的,所以此时
    39                 setTimeout里的this就变成了[object Window]window对象。
    40 
    41              */
    42 
    43 
    44 
    45         </script>
    46     </head>
    47     <body>
    48         
    49     </body>
    50 </html>
    View Code

    浏览器效果;

     问题原因见代码注释。

    上面现象解决方案:

    和上面一样主要是自定义一个变量,用来储存当前的this

     示例4

     1 <!DOCTYPE html>
     2 <html lang="en">
     3     <head>
     4         <meta charset="UTF-8">
     5         <title>Document</title>
     6         <script>
     7             function Bbb(){
     8                 this.b = 20;
     9                 var _this = this;
    10 
    11                 //传参 == 赋值
    12                 setTimeout(function(){
    13                     _this.show();
    14                 }, 4000);
    15             }
    16             Bbb.prototype.show = function(){
    17                 alert(this.b);
    18             }
    19 
    20             var b1 = new Bbb();
    21             alert(b1.b);//20
    22             b1.show();//20
    23 
    24             /*
    25             4s后弹出的是20,
    26 
    27             用自定义变量记录函数Bbb里的this 既 b1,然后在匿名函数里调用b1的show方法即可,然后用
    28             匿名函数的方式给setTimeout传参。
    29             setTimeout(function(){ _this.show();}, 4000);
    30             等价于
    31             setTimeout(function(){ b1.show();}, 4000);
    32             所以每次都不会混乱了。
    33              */
    34 
    35 
    36         </script>
    37     </head>
    38     <body>
    39         
    40     </body>
    41 </html>
    View Code

    效果:

  • 相关阅读:
    Kindle Book Resource
    Windows远程桌面
    python列表常用方法
    python字符串操作简单方法
    PCA降维实验代码
    android底部菜单栏的编写
    android UI:Fragment碎片
    android开发学习——day8
    android开发学习——day7
    android开发学习——day6
  • 原文地址:https://www.cnblogs.com/taohuaya/p/9671120.html
Copyright © 2020-2023  润新知