zoukankan      html  css  js  c++  java
  • 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。这个跟第一点的全局函数调用的全局变量一样。

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

     

     

  • 相关阅读:
    并发运行的思维模型
    进程和线程的区别
    拿来主义
    同步组件合作和团队合作 让世界变得更美好
    strace a++;b++;a+b;
    System 88: GDB Overview
    numpy多维数组维度及添加轴的理解
    Numpy入门
    python列表list 和numpy.array区别
    数组的生成方法
  • 原文地址:https://www.cnblogs.com/thislbq/p/5738811.html
Copyright © 2011-2022 走看看