this容易混淆的示例
Posted taohuaya
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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>
浏览器效果:
可以看出点击页面按钮时没有弹出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>
效果:
问题解决。
我们再来看一下在定时器或者延时器中,出现的现象:
示例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>
浏览器效果;
问题原因见代码注释。
上面现象解决方案:
和上面一样主要是自定义一个变量,用来储存当前的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>
效果:
以上是关于this容易混淆的示例的主要内容,如果未能解决你的问题,请参考以下文章
以下代码片段是不是容易受到 Rails 5 中 SQL 注入的影响?