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(){
<span style="white-space:pre"> </span>console.log(this); //控制台输出: Window //this指向的是全局对象--window对象
<span style="white-space:pre"> </span> }
</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使用,<span style="font-family: Arial, Helvetica, sans-serif;">控制台输出: Window //this指向的是全局对象--window对象</span> </script>

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

【转】javascript运行机制之this详解的更多相关文章

  1. javascript解析机制、闭包详解

    js解析机制: js代码解析之前会创建一个如下的词法环境对象(仓库):LexicalEnvironment{ } 在扫描js代码时会把: 1.用声明的方式创建的函数的名字: 2.用var定义的变量的名 ...

  2. JavaScript运行机制详解

    JavaScript运行机制详解   var test = function(){ alert("test"); } var test2 = function(){ alert(& ...

  3. 从setTimeout谈JavaScript运行机制

    从setTimeout说起 众所周知,JavaScript是单线程的编程,什么是单线程,就是说同一时间JavaScript只能执行一段代码,如果这段代码要执行很长时间,那么之后的代码只能尽情地等待它执 ...

  4. 深入浅出JavaScript运行机制

    一.引子 本文介绍JavaScript运行机制,这一部分比较抽象,我们先从一道面试题入手: console.log(1); setTimeout(function(){ console.log(3); ...

  5. JavaScript运行机制与setTimeout

    前段时间,老板交给了我一个任务:通过setTimeout来延后网站某些复杂资源的请求.正好借此机会,将JavaScript运行机制和setTimeout重新认真思考一遍,并将我对它们的理解整理如下. ...

  6. Javascript 调试利器 Firebug使用详解

    Javascript 调试利器 Firebug使用详解 有时候,为了更清楚方便的查看输出信息,我们可能需要将一些调试信息进行分组输出,那么可以使用console.group来对信息进行分组,在组信息输 ...

  7. javascript中的this作用域详解

    javascript中的this作用域详解 Javascript中this的指向一直是困扰我很久的问题,在使用中出错的机率也非常大.在面向对象语言中,它代表了当前对象的一个引用,而在js中却经常让我觉 ...

  8. 大数据学习笔记——Spark工作机制以及API详解

    Spark工作机制以及API详解 本篇文章将会承接上篇关于如何部署Spark分布式集群的博客,会先对RDD编程中常见的API进行一个整理,接着再结合源代码以及注释详细地解读spark的作业提交流程,调 ...

  9. 深入理解JavaScript运行机制

    深入理解JavaScript运行机制 前言 本文是写作在给团队新人培训之际,所以其实本文的受众是对JavaScript的运行机制不了解或了解起来有困难的小伙伴.也就是说,其实真正的原理和本文阐述的并不 ...

随机推荐

  1. ycsb使用方法

    ycsb本身相当于客户端,不断向服务端发送请求,同时记录下这些请求耗费的时间. 那么,必须要有一个服务端在某个端口监听. ycsb可以在workload里写入服务端的ip和端口,也可以在命令行里写上. ...

  2. js原型

    1.js基本类型和对象类型 js的简单类型包括数字(其中NaN为数字类型).字符串(类似'A'为字符,js没字符类型).布尔值.null值和undefined值.其他所有的值都是对象.数字.字符串和布 ...

  3. struts2 学习记录 过滤器 国际化

    struts2接触不是一天两天了,但是一直没有用它做什么项目,但老师确一直说它有很大的学习价值,所以还是把我学习到的东西给记录一下,记录的东西没有规律,只是给自己留个备份, struts2中最关键的是 ...

  4. python基础整理笔记(二)

    一. 列表 1. 创建实例: a = [1,2,3] b = list() 2. 主要支持的操作及其时间复杂度如下: 3. 其他 python中的列表,在内存中实际存储的形式其实是分散的存储,比较类似 ...

  5. Makefile技术和应用总结

    如何学习和运用Makefile 怎么写Makefile?不想讲太多如何如何做.Makefile这东西,公司让一两个人来负责就好了,否则一定是一锅粥.每次看到招聘广告里说,要求懂Makefile,懂Li ...

  6. (Gym 100685G) Gadget Hackwrench(LCA在线ST)

    Gadget Hackwrench time limit per test 2 seconds memory limit per test 64 megabytes input standard in ...

  7. 临时表VS表变量--因地制宜,合理使用

    一直以来大家对临时表与表变量的孰优孰劣争论颇多,一些技术群里的朋友甚至认为表变量几乎一无是处,比如无统计信息,不支持事务等等.但事实并非如此.这里我就临时表与表变量做个对比,对于大多数人不理解或是有歧 ...

  8. 【Leetcode】【Hard】Valid Number

    Validate if a given string is numeric. Some examples:"0" => true" 0.1 " => ...

  9. 在Linux CentOS上编译CoreCLR

    经过几天的努力,终于解决了在CentOS上编译CoreCLR的问题.最终发现问题是CMAKE_C_FLAGS的设置引起的. 只要在“src/pal/tools/clang-compiler-overr ...

  10. 使用FEST-Swing测试GUI

          在Java中最常用的单元测试工具要算JUnit了.FEST-Swing是一个能够与JUnit集成的GUI测试框架.使用FEST-Swing可以更方便的对Swing进行一系列的测试.下面就说 ...