zoukankan      html  css  js  c++  java
  • 01---JavaScript之this篇

          JavaScript 是一种脚本语言,因此被很多人认为是简单易学的。然而情况恰恰相反,JavaScript 支持函数式编程、闭包、基于原型的继承等高级功能。JavaScript 中的 this 关键字在不同情况下所指的含义均不相同。

      在 Java 等面向对象的语言中,this 关键字的含义是明确且具体的,即指代当前对象。一般在编译期确定下来,或称为编译期绑定。而在 JavaScript 中,this 是动态绑定,或称为运行期绑定的,这就导致 JavaScript 中的 this 关键字有能力具备多重含义,带来灵活性的同时,也为带来不少困惑。

    1. Java 语言中的 this

      在 Java 中定义类经常会使用 this 关键字,多数情况下是为了避免命名冲突,比如在下面例子的中,定义一个 Point 类,很自然的,大家会使用 x,y 为其属性或成员变量命名,在构造函数中,使用 x,y 为参数命名,相比其他的名字,比如 a,b,也更有意义。这时候就需要使用 this 来避免命名上的冲突。另一种情况是为了方便的调用其他构造函数,比如定义在 x 轴上的点,其 x 值默认为 0,使用时只要提供 y 值就可以了,我们可以为此定义一个只需传入一个参数的构造函数。无论哪种情况,this 的含义是一样的,均指当前对象。

    代码1

    public class Point {

        private int x = 0;

        private int y = 0;

       

        public Point(x, y){

            this.x = x;

            this.y = y;

        }

        public Point(y){

            this(0, y);

        }

     }

    2. JavaScript 语言中的 this

      由于其运行期绑定的特性,JavaScript 中的 this 含义要丰富得多,它可以是全局对象、当前对象或者任意对象,这完全取决于函数的调用方式。JavaScript 中函数的调用有以下几种方式:作为对象方法调用,作为函数调用,作为构造函数调用,和使用 apply 或 call 调用。下面将按照调用方式的不同,分别讨论 this 的含义。

    1作为函数的this

      函数也可以直接被调用,此时 this 绑定到全局对象。在浏览器中,window 就是该全局对象。比如下面的例子:函数被调用时,this 被绑定到全局对象,接下来执行赋值语句,相当于隐式的声明了一个全局变量,这显然不是调用者希望的。

    代码2

    function click_this(x){

           this.x = x;

           var temp = "";

    }

    Firefox调试结果如下:

     

    2)作为对象的this

      在JavaScript中,函数也是对象,因此函数也可以作为一个对象的属性,此时该函数被称为该对象的方法,在使用这种方式调用时,this被自然绑定到该对象上。如下代码所示:

    代码3

    var point = {

           x : 0,

           y : 0,

           move : function(x, y){

               this.x += x;

               this.y += y;

           }

        };

        point.move(10, 20);

    Firefox中调试结果如下图:

     

    3作为对象函数的内部函数的this

      当javascript对象中有函数时,函数内部又定义了一个内部函数,这时内部函数的this将会绑定全局对象即window而非对象本身。代码示例如下:

    代码4

    var point = {

           x : 0,

           y : 0,

           move : function(x, y){

               function moveTo(x, y){

                  this.x += x;

                  this.y += y;

               }

               moveTo(x, y);

           }

        };

        point.move(10, 20);

    Firefox调试结果如下:

     

      这属于 JavaScript 的设计缺陷,正确的设计方式是内部函数的 this 应该绑定到其外层函数对应的对象上,为了规避这一设计缺陷,聪明的 JavaScript 程序员想出了变量替代的方法,约定俗成,该变量一般被命名为 that。

    4使用 apply call 调用

      在 JavaScript 中函数也是对象,对象则有方法,apply 和 call 就是函数对象的方法。这两个方法异常强大,他们允许切换函数执行的上下文环境(context),即 this 绑定的对象。很多 JavaScript 中的技巧以及类库都用到了该方法。

      在使用apply和call中使用this时,当作为函数调用时,this绑定的是全局对象即window;当作为方法调用时,this绑定的是对象本身。

    3. 函数的执行环境

      JavaScript 中的函数既可以被当作普通函数执行,也可以作为对象的方法执行,这是导致 this 含义如此丰富的主要原因。一个函数被执行时,会创建一个执行环(Execution Context),函数的所有的行为均发生在此执行环境中,构建该执行环境时,JavaScript 首先会创建 arguments变量,其中包含调用函数时传入的参数。接下来创建作用域链。然后初始化变量,首先初始化函数的形参表,值为 arguments变量中对应的值,如果 arguments变量中没有对应值,则该形参初始化为 undefined。如果该函数中含有内部函数,则初始化这些内部函数。如果没有,继续初始化该函数内定义的局部变量,需要注意的是此时这些变量初始化为 undefined,其赋值操作在执行环境(Execution Context)创建成功后,函数执行时才会执行,这点对于理解 JavaScript 中的变量作用域非常重要。最后为 this变量赋值,如前所述,会根据函数调用方式的不同,赋给 this全局对象,当前对象等。至此函数的执行环境(Execution Context)创建成功,函数开始逐行执行,所需变量均从之前构建好的执行环境(Execution Context)中读取。

    参考资料:

    深入浅出 JavaScript 中的 this---

    http://www.ibm.com/developerworks/cn/web/1207_wangqf_jsthis/#toggle

  • 相关阅读:
    移动端常用状态
    css 动画
    jQuery源码解析 -- 概述
    Bearer Token && JWT --- 深入理解令牌机制
    字符串 ----> switch-case 语句
    Vuejs选项: provide/inject
    本地windows系统-》windows云服务器文件上传
    CSS基础点
    函数的调用 与 this
    两个有意思的网站
  • 原文地址:https://www.cnblogs.com/itachi/p/3728801.html
Copyright © 2011-2022 走看看