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 相关文章推荐
详解jQuery插件开发中的extend方法
Nov 19 Javascript
jquery动态改变div宽度和高度
Feb 09 Javascript
EasyUI中实现form表单提交的示例分享
Mar 01 Javascript
javascript HTML5文件上传FileReader API
Mar 27 Javascript
jQuery图片拖动组件Dropzone用法示例
Jan 17 Javascript
easyUI combobox实现联动效果
Jan 17 Javascript
jQuery插件HighCharts实现的2D堆条状图效果示例【附demo源码下载】
Mar 14 Javascript
详解html-webpack-plugin用法全解
Jan 22 Javascript
axios 处理 302 状态码的解决方法
Apr 10 Javascript
node前端开发模板引擎Jade的入门
May 11 Javascript
ndm:NPM的桌面GUI应用程序
Oct 15 Javascript
js数组的基本使用总结
Jan 18 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读取本地文件常用函数(fopen与file_get_contents)
2013/09/09 PHP
php调用新浪短链接API的方法
2014/11/08 PHP
PHP实现数据库的增删查改功能及完整代码
2018/04/18 PHP
写的htc的数据表格
2007/01/20 Javascript
仅IE9/10同时支持script元素的onload和onreadystatechange事件分析
2011/04/27 Javascript
JS实现双击屏幕滚动效果代码
2015/10/28 Javascript
JavaScript学习笔记之数组求和方法
2016/03/23 Javascript
Java框架SSH结合Easyui控件实现省市县三级联动示例解析
2016/06/12 Javascript
BootStrap selectpicker
2016/06/20 Javascript
MUI  Scroll插件的使用详解
2017/04/13 Javascript
Vue学习笔记进阶篇之过渡状态详解
2017/07/14 Javascript
基于JavaScript实现五子棋游戏
2020/08/26 Javascript
浅谈angular4实际项目搭建总结
2017/12/01 Javascript
vue.js简单配置axios的方法详解
2017/12/13 Javascript
layer弹出层全屏及关闭方法
2018/08/17 Javascript
脚手架vue-cli工程webpack的基本用法详解
2018/09/29 Javascript
实例介绍JavaScript中多种组合继承
2019/01/20 Javascript
微信小程序—setTimeOut定时器的问题及解决
2019/07/26 Javascript
基于layui的table插件进行复选框联动功能的实现方法
2019/09/19 Javascript
vue3.0 的 Composition API 的使用示例
2020/10/26 Javascript
python查找指定具有相同内容文件的方法
2015/06/28 Python
详解Python中dict与set的使用
2015/08/10 Python
python 计算两个日期相差多少个月实例代码
2017/05/24 Python
Python中new方法的详解
2019/01/15 Python
Django Sitemap 站点地图的实现方法
2019/04/29 Python
python 基于TCP协议的套接字编程详解
2019/06/29 Python
解决HTML5手机端页面缩放的问题
2017/10/27 HTML / CSS
Html5 canvas画图白板踩坑
2020/06/01 HTML / CSS
一句话工作感言
2014/03/01 职场文书
优秀家长事迹材料
2014/05/17 职场文书
师德师风建设整改措施思想汇报
2014/10/11 职场文书
歌咏比赛口号大全
2015/12/25 职场文书
利用Selenium添加cookie实现自动登录的示例代码(fofa)
2021/05/08 Python
使用goaccess分析nginx日志的详细方法
2021/07/09 Servers
linux下安装redis图文详细步骤
2021/12/04 Redis
详解Python flask的前后端交互
2022/03/31 Python