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
Nov 25 Javascript
Jquery读取URL参数小例子
Aug 30 Javascript
使用原生js写的一个简单slider
Apr 29 Javascript
详解webpack 如何集成第三方js库
Jun 29 Javascript
微信小程序实现给嵌套template模板传递数据的方式总结
Dec 18 Javascript
JS基于Location实现访问Url、重定向及刷新页面的方法分析
Dec 03 Javascript
[原创]微信小程序获取网络类型的方法示例
Mar 01 Javascript
详解用场景去理解函数柯里化(入门篇)
Apr 11 Javascript
详解JavaScript中的强制类型转换
Apr 15 Javascript
基于iview-admin实现动态路由的示例代码
Oct 02 Javascript
VueJS实现用户管理系统
May 29 Javascript
如何用JavaScript实现一个数组惰性求值库
May 05 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学习之正则表达式
2011/04/17 PHP
typecho插件编写教程(二):写一个新插件
2015/05/28 PHP
yii2分页之实现跳转到具体某页的实例代码
2016/06/02 PHP
php实现base64图片上传方式实例代码
2017/02/22 PHP
如何通过View::first使用Laravel Blade的动态模板详解
2017/09/21 PHP
jQuery AJAX回调函数this指向问题
2010/02/08 Javascript
jquery isEmptyObject判断是否为空对象的函数
2011/02/14 Javascript
Javascript面向对象编程(三) 非构造函数的继承
2011/08/28 Javascript
extjs实现选择多表自定义查询功能 前台部分(ext源码)
2011/12/20 Javascript
javascript获取鼠标点击元素对象(示例代码)
2013/12/20 Javascript
一些老手都不一定知道的JavaScript技巧
2014/05/06 Javascript
AngularJS表单编辑提交功能实例
2015/02/13 Javascript
NodeJS处理Express中异步错误
2017/03/26 NodeJs
从零开始学习Node.js系列教程之设置HTTP头的方法示例
2017/04/13 Javascript
ES6中javascript实现函数绑定及类的事件绑定功能详解
2017/11/08 Javascript
node.js基于express使用websocket的方法
2017/11/09 Javascript
浅谈js获取ModelAndView值的问题
2018/03/28 Javascript
Vue如何使用混合Mixins和插件开发详解
2020/02/05 Javascript
Python中的默认参数详解
2015/06/24 Python
ubuntu17.4下为python和python3装上pip的方法
2018/06/12 Python
python模拟键盘输入 切换键盘布局过程解析
2019/08/15 Python
Python 利用邮件系统完成远程控制电脑的实现(关机、重启等)
2019/11/19 Python
python实现从wind导入数据
2019/12/03 Python
Python+OpenCV图像处理——实现直线检测
2020/10/23 Python
html5+css3之CSS中的布局与Header的实现
2014/11/21 HTML / CSS
HTML5边玩边学(3)像素和颜色
2010/09/21 HTML / CSS
艺术用品:Arteza
2018/11/25 全球购物
牦牛毛户外探险服装:Kora
2019/02/08 全球购物
荷兰家电购物网站:Expert.nl
2020/01/18 全球购物
个人委托书
2014/07/31 职场文书
2014年科协工作总结
2014/12/09 职场文书
2016新年致辞
2015/08/01 职场文书
2019学校请假条格式及范文
2019/06/25 职场文书
Pyhton模块和包相关知识总结
2021/05/12 Python
Python list列表删除元素的4种方法
2021/11/01 Python
java中为什么说子类的构造方法默认访问的是父类的无参构造方法
2022/04/13 Java/Android