javascript运行机制之this详细介绍


Posted in Javascript onFebruary 07, 2014

this是面向对象语言中一个重要的关键字,理解并掌握该关键字的使用对于我们代码的健壮性及优美性至关重要。而javascript的this又有区别于Java、C#等纯面向对象的语言,这使得this更加扑朔迷离,让人迷惑。

this使用到的情况:
1. 纯函数
2. 对象方法调用
3. 使用new调用构造函数
4. 内部函数
5. 使用call / apply
6.事件绑定

1. 纯函数

var name = 'this is window';  //定义window的name属性  
function getName(){  
       console.log(this);    //控制台输出: Window  //this指向的是全局对象--window对象  
       console.log(this.name);  //控制台输出: this is window  /  
}    
getName(); 

运行结果分析:纯函数中的this均指向了全局对象,即window。

2. 对象方法调用

var name = 'this is window';  //定义window的name属性,看this.name是否会调用到  
var testObj = {  
    name:'this is testObj',  
    getName:function(){  
        console.log(this);  //控制台输出:testObj   //this指向的是testObj对象  
        console.log(this.name);  //控制台输出: this is testObj  
    }  
}  testObj.getName(); 

运行结果分析:被调用方法中this均指向了调用该方法的对象。

3.  使用new调用构造函数

function getObj(){  
    console.log(this);    //控制台输出: getObj{}  //this指向的新创建的getObj对象  
}  new getObj(); 

运行结果分析:new 构造函数中的this指向新生成的对象。

4. 内部函数

var name = "this is window";  //定义window的name属性,看this.name是否会调用到  
var testObj = {  
    name : "this is testObj",  
    getName:function(){  
        //var self = this;   //临时保存this对象  
        var handle = function(){  
            console.log(this);   //控制台输出: Window  //this指向的是全局对象--window对象  
            console.log(this.name);  //控制台输出: this is window    
            //console.log(self);  //这样可以获取到的this即指向testObj对象  
        }  
        handle();  
    }  
}  testObj.getName();

运行结果分析:内部函数中的this仍然指向的是全局对象,即window。这里普遍被认为是JavaScript语言的设计错误,因为没有人想让内部函数中的this指向全局对象。一般的处理方式是将this作为变量保存下来,一般约定为that或者self,如上述代码所示。

5. 使用call / apply

var name = 'this is window';  //定义window的name属性,看this.name是否会调用到  
var testObj1 = {  
    name : 'this is testObj1',  
    getName:function(){  
        console.log(this);   //控制台输出: testObj2  //this指向的是testObj2对象  
        console.log(this.name);  //控制台输出: this is testObj2    
    }  
}  var testObj2 = {  
    name: 'this is testObj2'  
}  
testObj1.getName.apply(testObj2);  
testObj1.getName.call(testObj2); 

Note:apply和call类似,只是两者的第2个参数不同:
[1] call( thisArg [,arg1,arg2,… ] );  // 第2个参数使用参数列表:arg1,arg2,... 
[2] apply(thisArg [,argArray] );     //第2个参数使用 参数数组:argArray
运行结果分析:使用call / apply  的函数里面的this指向绑定的对象。

6. 事件绑定
事件方法中的this应该是最容易让人产生疑惑的地方,大部分的出错都源于此。

//页面Element上进行绑定  
  <script type="text/javascript">  
     function btClick(){  
        console.log(this);  //控制台输出: Window  //this指向的是全局对象--window对象  
    }  
  </script>  
  <body>  
    <button id="btn" onclick="btClick();" >点击</button>  
  </body> 
//js中绑定方式(1)  
  <body>  
    <button id="btn">点击</button>  
  </body>  
  <script type="text/javascript">  
     function btClick(){  
        console.log(this);  //控制台输出:<button id="btn">点击</button>  //this指向的是Element按钮对象  
     }       document.getElementById("btn").onclick = btClick;  
     document.getElementById("btn").onclick;    
  </script> 
//js中绑定方式(2)  
<body>  
   <button id="btn">点击</button>  
 </body>  
 <script type="text/javascript">  
    document.getElementById("btn").onclick = function(){  
     console.log(this);  //控制台输出:<button id="btn">点击</button>  //this指向的是Element按钮对象  
    }  
    document.getElementById("btn").onclick;  
 </script> 
//js中绑定方式(3)  
<body>  
   <button id="btn">点击</button>  
 </body>  
 <script type="text/javascript">  
    function btClick(){  
        console.log(this);    
     }      document.getElementById("btn").addEventListener('click',btClick); //控制台输出:<button id="btn">点击</button>  //this指向的是Element按钮对象把函数(方法)用在事件处理的时候。  
    document.getElementById("btn").attachEvent('onclick',btClick);  //IE使用,控制台输出: Window  //this指向的是全局对象--window对象  
 </script> 

运行结果分析:以上2种常用事件绑定方法,在页面Element上的进行事件绑定(onclick="btClick();"),this指向的是全局对象;而在js中进行绑定,除了attachEvent绑定的事件方法外,this指向的是绑定事件的Elment元素。

Javascript 相关文章推荐
JS input 数字验证代码
Jul 30 Javascript
需要做特殊处理的DOM元素属性的访问
Nov 05 Javascript
Jquery操作radio的简单实例
Jan 06 Javascript
javasciprt下jquery函数$.post执行无响应的解决方法
Mar 13 Javascript
jquery实现通用版鼠标经过淡入淡出效果
Jun 15 Javascript
《JavaScript DOM 编程艺术》读书笔记之JavaScript 语法
Jan 09 Javascript
js实现每日自动换一张图片的方法
May 04 Javascript
Javascript实现获取及设置光标位置的方法
Jul 21 Javascript
基于jquery实现即时检查格式是否正确的表单
May 06 Javascript
Vue与Node.js通过socket.io通信的示例代码
Jul 25 Javascript
Js实现复选框的全选、全不选反选功能代码实例
Feb 28 Javascript
js实现鼠标拖曳效果
Dec 30 Javascript
jQuery获取当前对象标签名称的方法
Feb 07 #Javascript
JQuery与Ajax调用新浪API获取短网址的代码
Feb 07 #Javascript
jquery Ajax 实现加载数据前动画效果的示例代码
Feb 07 #Javascript
jquery.ajax的url中传递中文乱码问题的解决方法
Feb 07 #Javascript
jquery ajax传递中文参数乱码问题及解决方法说明
Feb 07 #Javascript
Ajax提交与传统表单提交的区别说明
Feb 07 #Javascript
JQUERY 设置SELECT选中项代码
Feb 07 #Javascript
You might like
PHP分页类集锦
2014/11/18 PHP
php array_merge函数使用需要注意的一个问题
2015/03/30 PHP
PHP生成树的方法
2015/07/28 PHP
php提取身份证号码中的生日日期以及验证是否为成年人的函数
2015/09/29 PHP
PHP5.2中PDO的简单使用方法
2016/03/25 PHP
PHP7匿名类用法分析
2016/09/26 PHP
PHP实现对文件锁进行加锁、解锁操作的方法
2017/07/04 PHP
PHP中cookie知识点学习
2018/05/06 PHP
Web层改进II-用xmlhttp 无声息提交复杂表单
2007/01/22 Javascript
点击页面其它地方隐藏该div的两种思路
2013/11/18 Javascript
vue实现列表的添加点击
2016/12/29 Javascript
详解Vue2.X的路由管理记录之 钩子函数(切割流水线)
2017/05/02 Javascript
详解使用Node.js 将txt文件转为Excel文件
2017/07/05 Javascript
详解基于webpack2.x的vue2.x的多页面站点
2017/08/21 Javascript
详解vue中async-await的使用误区
2018/12/05 Javascript
vue列表单项展开收缩功能之this.$refs的详解
2019/05/05 Javascript
js实现数字滚动特效
2019/12/16 Javascript
vue实现单一筛选、删除筛选条件
2020/10/26 Javascript
基于JavaScript实现轮播图效果
2021/01/02 Javascript
Python 可爱的大小写
2008/09/06 Python
python中numpy基础学习及进行数组和矢量计算
2017/02/12 Python
Python扩展内置类型详解
2018/03/26 Python
如何在Django中设置定时任务的方法示例
2019/01/18 Python
TensorFlow2.X结合OpenCV 实现手势识别功能
2020/04/08 Python
python如何导出微信公众号文章方法详解
2020/08/31 Python
使用sublime text3搭建Python编辑环境的实现
2021/01/12 Python
2021年值得向Python开发者推荐的VS Code扩展插件
2021/01/25 Python
如何将无状态会话Bean发布为WEB服务,只有无状态会话Bean可以发布为WEB服务?
2015/12/03 面试题
幼师专业毕业生自荐信
2013/09/29 职场文书
表彰先进集体通报
2014/01/12 职场文书
《雾凇》教学反思
2014/02/17 职场文书
《钱学森》听课反思
2014/03/01 职场文书
人力资源总监工作说明
2014/03/03 职场文书
2014年秋季开学演讲稿
2014/05/24 职场文书
2015年学校少先队工作总结
2015/07/20 职场文书
2019同学聚会主持词
2019/05/06 职场文书