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 相关文章推荐
JavaScript 编写匿名函数的几种方法
Feb 21 Javascript
JSQL 批量图片切换的实现代码
May 05 Javascript
JS中获取函数调用链所有参数的方法
May 07 Javascript
js中函数声明与函数表达式
Jun 03 Javascript
JS实现弹性菜单效果代码
Sep 07 Javascript
BootStrap Typeahead自动补全插件实例代码
Aug 10 Javascript
AngularJS  $on、$emit和$broadcast的使用
Sep 05 Javascript
js实现倒计时及时间对象
Nov 15 Javascript
Bootstrap路径导航与分页学习使用
Feb 08 Javascript
解决vue prop传值default属性如何使用,为何不生效的问题
Sep 21 Javascript
浅析我对JS延迟异步脚本的思考
Oct 12 Javascript
JavaScript offset实现鼠标坐标获取和窗口内模块拖动
May 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判断变量是否为0的方法
2014/02/08 PHP
php微信公众平台配置接口开发程序
2016/09/22 PHP
Yii2针对游客、用户防范规则和限制的解决方法分析
2016/10/08 PHP
重定向实现代码
2006/11/20 Javascript
js 实现打印网页中定义的部分内容的代码
2010/04/01 Javascript
js下写一个事件队列操作函数
2010/07/19 Javascript
原生javascript模仿win8等待提示圆圈进度条
2014/04/24 Javascript
JavaScript中九种常用排序算法
2014/09/02 Javascript
微信小程序  modal详解及实例代码
2016/11/09 Javascript
详解Angular 4.x 动态创建组件
2017/04/25 Javascript
浅谈react 同构之样式直出
2017/11/07 Javascript
bootstrap实现二级下拉菜单效果
2017/11/23 Javascript
element ui 对话框el-dialog关闭事件详解
2018/02/26 Javascript
剖析Angular Component的源码示例
2018/03/23 Javascript
koa2实现登录注册功能的示例代码
2018/12/03 Javascript
巧妙运用v-model实现父子组件传值的方法示例
2019/04/07 Javascript
浅谈Javascript中的对象和继承
2019/04/19 Javascript
vue实现的上拉加载更多数据/分页功能示例
2019/05/25 Javascript
node 解析图片二维码的内容代码实例
2019/09/11 Javascript
python matlibplot绘制3D图形
2018/07/02 Python
Python FFT合成波形的实例
2019/12/04 Python
将tensorflow.Variable中的某些元素取出组成一个新的矩阵示例
2020/01/04 Python
python 利用jieba.analyse进行 关键词提取
2020/12/17 Python
Python tkinter之Bind(绑定事件)的使用示例
2021/02/05 Python
css3 利用transform打造走动的2D时钟
2020/10/20 HTML / CSS
美国玩具公司:U.S.Toy
2018/05/19 全球购物
美国酒店控股公司:Choice Hotels
2018/06/15 全球购物
泰国国际航空公司官网:Thai Airways International
2019/12/04 全球购物
大学生就业自荐信
2013/10/26 职场文书
中英双版中文教师求职信
2013/10/27 职场文书
运动会通讯稿100字
2014/01/31 职场文书
遗嘱继承权公证书
2015/01/26 职场文书
大班上学期个人总结
2015/02/13 职场文书
党风廉政建设个人总结
2015/03/06 职场文书
Django中session进行权限管理的使用
2021/07/09 Python
Golang 对es的操作实例
2022/04/20 Golang