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拖拽排序效果实现代码
Sep 20 Javascript
JS判断表单输入是否为空(示例代码)
Dec 23 Javascript
jquery列表拖动排列(由项目提取相当好用)
Jun 17 Javascript
JavaScript实现找出数组中最长的连续数字序列
Sep 03 Javascript
jQuery选择器源码解读(三):tokenize方法
Mar 31 Javascript
AngularJS 指令的交互详解及实例代码
Sep 14 Javascript
微信小程序开发之数据存储 参数传递 数据缓存
Apr 13 Javascript
jquery单击文字或图片内容放大并居中显示
Jun 23 jQuery
深入理解vue2.0路由如何配置问题
Jul 18 Javascript
vue3.0 CLI - 2.1 -  component 组件入门教程
Sep 14 Javascript
Nuxt.js开启SSR渲染的教程详解
Nov 30 Javascript
webpack HappyPack实战详解
Oct 08 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中获取系统信息的方法
2013/06/25 PHP
yii框架配置默认controller和action示例
2014/04/30 PHP
php中foreach结合curl实现多线程的方法分析
2016/09/22 PHP
laravel 解决强制跳转 https的问题
2019/10/22 PHP
Javascript优化技巧(文件瘦身篇)
2008/01/28 Javascript
jQuery EasyUI API 中文文档 - ComboGrid 组合表格
2011/10/13 Javascript
jquery 插件学习(一)
2012/08/06 Javascript
node.js实现逐行读取文件内容的代码
2014/06/27 Javascript
招聘网站基于jQuery实现自动刷新简历
2015/05/10 Javascript
Jquery解析json字符串及json数组的方法
2015/05/29 Javascript
jQuery动画效果相关方法实例分析
2015/12/31 Javascript
JS实现随页面滚动显示/隐藏窗口固定位置元素
2016/02/26 Javascript
AngularJS基础 ng-repeat 指令简单示例
2016/08/03 Javascript
关于react-router的几种配置方式详解
2017/07/24 Javascript
EasyUI创建人员树的实例代码
2017/09/15 Javascript
JS原型继承四步曲及原型继承图一览
2017/11/28 Javascript
Angular实现点击按钮后在上方显示输入内容的方法
2017/12/27 Javascript
Nodejs实现的操作MongoDB数据库功能完整示例
2019/02/02 NodeJs
javascript数组去重方法总结(推荐)
2019/03/20 Javascript
使vue实现jQuery调用的两种方法
2019/05/12 jQuery
简单谈谈javascript高级特性
2019/09/04 Javascript
微信小程序复选框实现多选一功能过程解析
2020/02/14 Javascript
Python中统计函数运行耗时的方法
2015/05/05 Python
Python对列表排序的方法实例分析
2015/05/16 Python
Pycharm学习教程(4) Python解释器的相关配置
2017/05/03 Python
利用aardio给python编写图形界面
2017/08/21 Python
python多线程socket编程之多客户端接入
2017/09/12 Python
Django中的Signal代码详解
2018/02/05 Python
详解基于django实现的webssh简单例子
2018/07/17 Python
Python pandas RFM模型应用实例详解
2019/11/20 Python
python利用蒙版抠图(使用PIL.Image和cv2)输出透明背景图
2020/08/04 Python
医学实习生自我鉴定
2013/12/12 职场文书
社团文化节邀请函
2014/01/10 职场文书
鼓舞士气的口号
2014/06/16 职场文书
党员读书活动心得体会
2016/01/14 职场文书
Node.js实现断点续传
2021/06/23 Javascript