在JavaScript的学习当中,this关键字的出现频率可不低,所以想想有必要对this关键字做一个总结。在总结过程中,参考的资料来源于书本及网上。

一、定义

1、this是函数内部的一个特殊对象(或this引用)--它引用的是函数据以执行的环境对象。(来源于JavaScript高级程序设计)

2、this引用是一种在JavaScript的代码中随时都可以使用的只读变量。 this引用 引用(指向)的是一个对象,它有着会根据代码上下文语境自动改变其引用对象的特性。它的引用规则如下:

• 在最外层代码中,this引用 引用的是全局对象。

• 在函数内,this引用根据函数调用的方式的不同而有所不同。如下

1)构造函数的调用--this引用 引用的是所生成的对象

2)方法调用--this引用 引用的是接收方对象

3)apply或call调用--this引用 引用的是有apply或call的参数指定的对象

4)其他方式的调用--this引用 引用的是全局对象

(来源于JavaScript编程全解)

二、根据以上所述及网上的相关资料,this对象(引用)的使用情况总结如下:

JavaScript是动态语言,this关键字在执行的时候才能确定是谁。所以this永远指向调用者,即对“调用对象”的引用。简单点说就是调用的方法属于哪个对象,this就指向那个对象。根据函数调用方式的不同,this可以 指向全局对象,当前对象,或其他任意对象。

1、全局函数调用,全局函数中的this会指向全局对象window。(函数调用模式)

 //代码清单1
<script type="text/javascript">
var message = "this in window"; //这一句写在函数外面和里面是一样效果
function func() {
if(this == window){
alert("this == window");
alert(message);
this.methodA = function() {
alert("I'm a function");
}
}
} func(); //如果不调用func方法,则里面定义的属性或方法会取不到
methodA();
</script>

func()的调用结果为this == window, this in window

methodA()的调用结果为I'm a function

2、构造函数调用,即使用new的方式实例化一个对象,this会指向通过构造函数生成的对象。(构造器调用模式)

 代码清单2
<script type="text/javascript">
function Func() {
if (this == window) {
alert("this == window");
}
else {
alert("this != window");
}
this.fieldA = "I'm a field";
alert(this);
} var obj = new Func();
alert(obj.fieldA); //this指向的是对象obj
</script>

3、对象方法的调用,this指向当前对象。任何函数,只要该函数被当做一个对象的方法使用或赋值时,该函数内部的this都是对该对象本身的引用。也可理解为this写在一个普通对象中,this指向的就是对象本身。(方法调用模式)

(方法的定义: 作为对象属性的函数称为方法)

 //代码清单3
<script type="text/javascript">
var obj = {
x: 3,
doit: function(){
if(this == window){
alert("this == window");
}else{
alert("method is called: " + this.x);
}
}
}; obj.doit(); //this指向的是对象obj
</script>

4、通过apply或call方法调用,this指向传入的对象。

apply 或call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。  (apply调用模式)

 //代码清单4
<script type="text/javascript">
var obj = {
x: 3,
doit: function(){
alert("method is called: " + this.x);
}
};
var obj2 = {x: 4}; obj.doit(); //3,this指向obj
obj.doit.apply(obj2); //4,this指向obj2
obj.doit.call(obj2); //4,this指向obj2
</script>

5、原型链中的this --原型对象及构造函数中的this指向新创建的实例对象。使用prototype扩展方法可以使用this获取到源对象的实例,私有字段无法通过原型链获取。

 //代码清单5
<script type="text/javascript">
function Func() {
this.fieldA = "I'm a field";
var privateFieldA = "I'm a var";
} Func.prototype = {
ExtendMethod: function(str) {
alert(str + " :" + this.fieldA);
alert(privateFieldA); //出错,私有字段无法通过原型链获取。
}
}; var obj = new Func();
obj.ExtendMethod("From prototype"); //此时构造函数及原型链中的this指向对象obj
</script>

6、闭包中的this --闭包:写在function中的function,this指向全局对象window。

6.1 对象中的闭包

 //代码清单6
<script type="text/javascript">
var name = "The window";
var obj = {
name: "My Object",
getNameFunc: function(){
return function(){
return this.name;
}
}
}; alert(obj.getNameFunc()()); //The window
</script>

此时,闭包中的this指向全局对象window,只能取到全局对象的属性。那么对象内部的属性(外部函数的变量)要想访问又怎么办呢? 把外部函数的this对象保存在一个闭包能访问的变量就可以了。看如下代码:

 //代码清单7
<script type="text/javascript">
var name = "The window";
var obj = {
name: "My Object",
getNameFunc: function(){
var that = this;
return function(){
return that.name;
}
}
}; alert(obj.getNameFunc()()); //My object
</script>

将外部函数的this赋值给that变量,就能读取到外部函数的变量。

6.2 不管是直接引用function,还是实例化一个function,其返回的闭包函数里的this都是指向window。

 //代码清单8
<script type="text/javascript">
function a() {
alert(this == window);
var that = this;
var func = function() {
alert(this == window);
alert(that);
};
return func;
} var b = a();
b(); //true, true, [object Window]
var c = new a();
c(); //false, true, [object object]
</script>

7、函数使用bind()方法绑定一个对象,this会指向传给bind()函数的值。

 //代码清单9
<script type="text/javascript">
window.color = "red";
var obj = {color: "blue"};
function sayColor(){
alert(this.color);
} var objSayColor = sayColor.bind(obj);
objSayColor(); //blue
</script>

8、内嵌在HTML元素中的脚本段,this指向元素本身

 //代码清单10
<div onclick="test(this)" id="div">Click Me</div>
<script type="text/javascript">
function test(obj) {
alert(obj); //[object HTMLDivElement]
}
</script>

  9、写在script标签中:this就是指全局对象window。这个跟第一点的全局函数调用的全局变量一样。

以上总结的情况未必完整,若在工作中发现有其他情况再补充进来。

最新文章

  1. bootstrap按钮样式
  2. [Java入门笔记] Java语言简介
  3. C# 固定窗体大小且不能鼠标调整大小完美实现
  4. python统计英文首字母出现的次数
  5. 兼容现有jQuery API的轻量级JavaScript库:Zepo
  6. 《windows程序设计》学习_2.1:初识消息
  7. NUTZ中处理系统未捕获异常
  8. Underscore.js 的模板功能介绍与应用
  9. Activiti源代码分析
  10. MicroPython开发板:TPYBoard v102 播放音乐实例
  11. CCF系列之日期计算(201509-2)
  12. Maven以及在Maven在Myeclipse中的配置
  13. 隐藏文件的查看(Win/Linux/macOS)
  14. Maven学习(四)-- Maven的核心概念
  15. 折线图hellocharts的使用说明
  16. 嵌套if-esle语句
  17. vue项目中, 字段信息为空时不渲染,是真的不渲染吗
  18. JVM性能、多线程排查常用命令
  19. Python 字典的操作
  20. Oracle RAC 集群环境下日志文件结构

热门文章

  1. git使用经验
  2. 16进制字符串转换为byte数组
  3. Struts2 工作流程
  4. G - Bullseye
  5. #ifndef #define #endif 防止头文件被重复引用
  6. 为什么JavaScript函数中的参数前面不能加var
  7. java poi 导入excel
  8. wamp出现问题#1045 - Access denied for user &#39;root&#39;@&#39;localhost&#39; (using password: NO)的解决方法
  9. [ofbiz]entitymode中类型的对照关系
  10. Hadoop配置文件-mapred-site.xml