JavaScript中的this引用
在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。这个跟第一点的全局函数调用的全局变量一样。
以上总结的情况未必完整,若在工作中发现有其他情况再补充进来。
JavaScript中的this引用的更多相关文章
- JavaScript中:地址引用的特性,导致静态初始值被修改
问题分类 JavaScript,值引用,地址引用 问题描述 开发过程中,服务端将静态配置数据从mysql数据库中读取到内存中,方便调用. 在实现流派功能时,需从数据库中读取流派种类数据到内存中,由于其 ...
- JavaScript中var变量引用function与直接声明function
今天在h5开发app的过程中遇到了一个js问题,function的执行问题 在js中声明函数function有这两种方法 var A=function(){...} 或者 function A(){. ...
- javascript中的循环引用对象处理
先说明一下什么是循环引用对象: var a={"name":"zzz"}; var b={"name":"vvv"}; ...
- javaScript中的闭包原理 (译)
这篇文章通过javaScript代码解释了闭包的原理,来让编程人员理解闭包.它不是写给大牛或使用功能性语言进行编程的程序员的.一旦意会了其核心概念,闭包理解起来并不难.然而,你不可能通过阅读任何有关闭 ...
- javascript中值传递与值引用的研究
今天重新看了一下<javascript高级程序设计>,其中讲到了javascript中的值传递和值引用,所以就自己研读了一下,但是刚开始没有明白函数中的参数只有值传递,有的场景好像参数是以 ...
- 如何在JavaScript中正确引用某个方法(bind方法的应用)
在JavaScript中,方法往往涉及到上下文,也就是this,因此往往不能直接引用,就拿最常见的console.log("info…")来说,避免书写冗长的console,直接用 ...
- Javascript 中的闭包和引用
Javascript 中一个最重要的特性就是闭包的使用.因为闭包的使用,当前作用域总可以访问外部的作用域.因为Javascript 没有块级作用域,只有函数作用域,所以闭包的使用与函数是紧密相关的. ...
- JavaScript中,按值传递与按地址(引用)传递。
JavaScript中,数字型,字符串,布尔型等基本类型,传递给变量时,传递方式为按值传递,这个很好理解,不做多解释. 而令人有所疑惑的,是数组,对象等引用类型传递给变量是,传递方式为按地址传递.此处 ...
- JavaScript中基本数据类型和引用数据类型的区别
1.基本数据类型和引用数据类型 ECMAScript包括两个不同类型的值:基本数据类型和引用数据类型. 基本数据类型指的是简单的数据段,引用数据类型指的是有多个值构成的对象. 当我们把变量赋值给一个变 ...
随机推荐
- PES包头
PES是打包过的ES,已经插入PTS和DTS,一般是一个pes包为一帧图像 PES包格式: PES再打包成TS流或PS流,往往一个PES会分存到多个ts包中, start_code: 0x00 00 ...
- 查看Android数据库文件
使用Eclipse DDMS的File Explorer不能能看到Data目录下面的东西,可能由下面原因引起的 手机没有Root -- 可以使用Root大师 Data文件权限不够 -- 可以使用Ro ...
- 将已有项目导入Gitlab
登陆GitLab,创建添加项目. 写入项目的基本信息,包括名称.描述.权限等等. cd existing_folder git init git remote add origin git@10.10 ...
- div添加透明边框透明背景css
-webkit-box-shadow: 1px 0px 15px #696969; background: rgba(255, 255, 255, 0.45) none repeat scroll 0 ...
- 容器vector的使用总结 容器stack(栈)
0.头文件:#include<vector>; using namespace std; 1.定义: vector<type> vec; 2.迭代器 vector<typ ...
- java poi 导入excel
最近项目需要导入excel,网上有很多例子,自己整合记录下,兼容2003和2007,暂时没有添加图片处理功能. 所需jar包 http://pan.baidu.com/s/1sjPuWDR pack ...
- 第一章——Activity的生命周期
问题总结: 1.Activity完整的生命周期 2.当打开第二个Activity并关闭时候的生命周期. ①.解释为什么onPause()方法不要有耗时操作 3.Activity发生异常重启的时候问题: ...
- PHP学习笔记13淘宝接口开发一例(tmall.items.discount.search),PHP
程序设计,因为接口是有请求次数限制的,正式接口也只有2W次每天的请求次数,所以我们需要把从接口返回的数据缓存起来. 采用的接口是http://api.taobao.com/apidoc/api.htm ...
- 定制样式插入到ueditor
AngularJs定制样式插入到ueditor中的问题总结 总结一下自己给编辑器定制样式的过程中所遇到的问题,主要是编辑器的二次开发接口,以及用angular定制样式,问题不少,终于在**的帮助下,完 ...
- 山寨QQ音乐的布局(一)
学了两天IOS趁着还没忘光,巩固一下所学知识想做点东西,由于自己的设计能力有限,所以就山寨一下吧,说到山寨怎么能忘了腾讯呢,今天发现QQ音乐的设计风格是扁平化的,小清新风格,所以就山寨一下它吧.. 由 ...