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 //代码清单1
 2 <script type="text/javascript">
 3     var message = "this in window";    //这一句写在函数外面和里面是一样效果
 4     function func() {
 5         if(this == window){
 6             alert("this == window");
 7             alert(message);
 8             this.methodA = function() {
 9                 alert("I‘m a function");
10                 }
11         }
12     }
13
14     func();   //如果不调用func方法,则里面定义的属性或方法会取不到
15     methodA();
16 </script>

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

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

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

 1 代码清单2
 2 <script type="text/javascript">
 3     function Func() {
 4         if (this == window) {
 5             alert("this == window");
 6         }
 7         else {
 8             alert("this != window");
 9         }
10         this.fieldA = "I‘m a field";
11         alert(this);
12     }
13
14     var obj = new Func();
15     alert(obj.fieldA);    //this指向的是对象obj
16 </script>

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

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

 1 //代码清单3
 2 <script type="text/javascript">
 3     var obj = {
 4         x: 3,
 5         doit: function(){
 6             if(this == window){
 7                 alert("this == window");
 8             }else{
 9                 alert("method is called: " + this.x);
10             }
11         }
12     };
13
14     obj.doit();    //this指向的是对象obj
15 </script>

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

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

 1 //代码清单4
 2 <script type="text/javascript">
 3     var obj = {
 4         x: 3,
 5         doit: function(){
 6             alert("method is called: " + this.x);
 7         }
 8     };
 9     var obj2 = {x: 4};
10
11     obj.doit();    //3,this指向obj
12     obj.doit.apply(obj2);    //4,this指向obj2
13     obj.doit.call(obj2);    //4,this指向obj2
14 </script>

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

 1 //代码清单5
 2 <script type="text/javascript">
 3     function Func() {
 4         this.fieldA = "I‘m a field";
 5         var privateFieldA = "I‘m a var";
 6     }
 7
 8     Func.prototype = {
 9         ExtendMethod: function(str) {
10             alert(str + " :" + this.fieldA);
11             alert(privateFieldA);  //出错,私有字段无法通过原型链获取。
12         }
13      };
14
15     var obj = new Func();
16     obj.ExtendMethod("From prototype");   //此时构造函数及原型链中的this指向对象obj
17 </script>

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

6.1 对象中的闭包

 1 //代码清单6
 2 <script type="text/javascript">
 3     var name = "The window";
 4     var obj = {
 5         name: "My Object",
 6         getNameFunc: function(){
 7             return function(){
 8                 return this.name;
 9             }
10         }
11     };
12
13     alert(obj.getNameFunc()());    //The window
14 </script>

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

 1 //代码清单7
 2 <script type="text/javascript">
 3     var name = "The window";
 4     var obj = {
 5         name: "My Object",
 6         getNameFunc: function(){
 7             var that = this;
 8             return function(){
 9                 return that.name;
10             }
11         }
12     };
13
14     alert(obj.getNameFunc()());    //My object
15 </script>

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

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

 1 //代码清单8
 2 <script type="text/javascript">
 3     function a() {
 4         alert(this == window);
 5         var that = this;
 6         var func = function() {
 7             alert(this == window);
 8             alert(that);
 9         };
10         return func;
11      }
12
13     var b = a();
14     b();   //true, true, [object Window]
15     var c = new a();
16     c();  //false, true, [object object]
17 </script>

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

 1 //代码清单9
 2 <script type="text/javascript">
 3     window.color = "red";
 4     var obj = {color: "blue"};
 5     function sayColor(){
 6         alert(this.color);
 7     }
 8
 9     var objSayColor = sayColor.bind(obj);
10     objSayColor();   //blue
11 </script>

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

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

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

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

时间: 2024-10-13 12:07:30

JavaScript中的this引用的相关文章

JavaScript中var变量引用function与直接声明function

今天在h5开发app的过程中遇到了一个js问题,function的执行问题 在js中声明函数function有这两种方法 var A=function(){...} 或者 function A(){...} 第一种称之为变量引用函数,因为js允许函数作为一个值传递给变量,第二种是直接声明式函数 一直以为这两种没什么区别,然而,今天在使用过程中发现,当我使用第一种方式声明function的时候,如果如下这样: document.getElementById("xx").addEventL

javascript中的循环引用对象处理

先说明一下什么是循环引用对象: var a={"name":"zzz"}; var b={"name":"vvv"}; a.child=b; b.parent=a; 这里的a和b都是一个循环引用对象. 循环引用对象本来没有什么问题,序列化的时候才会发生问题,比如调用JSON.stringify()对该类对象进行序列化,就会报错: Converting circular structure to JSON.    而序列化需求很

如何在JavaScript中正确引用某个方法(bind方法的应用)

在JavaScript中,方法往往涉及到上下文,也就是this,因此往往不能直接引用,就拿最常见的console.log("info…")来说,避免书写冗长的console,直接用log("info…")代替,不假思索的会想到如下语法: 1 var log = console.log; 2 log("info…"); 很遗憾,运行报错:TypeError: Illegal invocation. 为啥呢?对于console.log("i

javascript中值传递与值引用的研究

今天重新看了一下<javascript高级程序设计>,其中讲到了javascript中的值传递和值引用,所以就自己研读了一下,但是刚开始没有明白函数中的参数只有值传递,有的场景好像参数是以引用的方式传递的,但是实际上却不是,那到底是怎么回事,或者是函数中的传值是值传递还是值引用呢,下面来对书上给出的例子做一个图解,这样能够更好的解释这个问题.有顿悟的感觉.javascript中貌似共有8种数据类型,包括了字符串类型,数值类型,布尔类型,undefined类型,null类型,对象,数组,函数:1

JavaScript中基本数据类型和引用数据类型的区别

1.基本数据类型和引用数据类型 ECMAScript包括两个不同类型的值:基本数据类型和引用数据类型. 基本数据类型指的是简单的数据段,引用数据类型指的是有多个值构成的对象. 当我们把变量赋值给一个变量时,解析器首先要确认的就是这个值是基本类型值还是引用类型值. 2.常见的基本数据类型: Number.String .Boolean.Null和Undefined.基本数据类型是按值访问的,因为可以直接操作保存在变量中的实际值.示例: var a = 10; var b = a; b = 20;

Javascript 中的闭包和引用

Javascript 中一个最重要的特性就是闭包的使用.因为闭包的使用,当前作用域总可以访问外部的作用域.因为Javascript 没有块级作用域,只有函数作用域,所以闭包的使用与函数是紧密相关的. 模拟私有变量 function Counter(start) { var count = start; return { increment: function() { count++; }, get: function() { return count; } } } var foo = Count

android中引用javascript和在javascript中引用java的简单例子

在android中通过微webView是可以加载javascript代码的,与其说是javascript不如说是加载网页,其实就是html和javascript的结合等,通过html和javascript也可以创建安卓应用,因为android和javascript可以相互调用,下面是我介绍的一个简单的例子,大家可以参考.欢迎和大家一起交流. //允许JavaScript执行 webSettings.setJavaScriptEnabled(true); // 添加一个对象, 让javascrip

【转】十个JavaScript中易犯的小错误,你中了几枪?

在今天,JavaScript已经成为了网页编辑的核心.尤其是过去的几年,互联网见证了在SPA开发.图形处理.交互等方面大量JS库的出现. 如果初次打交道,很多人会觉得js很简单.确实,对于很多有经验的工程师,或者甚至是初学者而言,实现基本的js功能几乎毫无障碍.但是JS的真实功能却比很多人想象的要更加多样.复杂.JavaScript的许多细节规定会让你的网页出现很多意想不到的bug,搞懂这些bug,对于成为一位有经验的JS开发者很重要. 常见错误一:对于this关键词的不正确引用 我曾经听一位喜

JavaScript中Function的拓展

Function 是什么东西,就是JavaScript中的顶级类,系统级别的类.我们平时写的函数方法例如下. function Animal() { } Animal就是Function的实例,但是在我们的逻辑中 Animal是类,是自定义类. Function是类,Animal是类也是实例,Animal是Function的实例,Animal是自定义类.这点大家一定要搞清楚. 我们在顶级类上定义一个method的方法,用于进行键值对的方式进行方法链式的设定, Function.prototype