javascript学习指南|javascript之this关键字详解介绍

更新时间:2017-09-05    来源:C语言    手机版     字体:

【www.bbyears.com--C语言】

因为在接触到它之前,大部分人认为this是那些oop语言的专利。至少我曾经是这么认为的。

随着时间的推移,对javascript的进一步提高。this那神秘的面纱才一步步被揭开。话休绕舌,下面就一起来看看这层神秘的面纱背后的this吧。

首先,我们要知道this是什么。它的含义。通俗的来说, this首先是一个对象,其次要知道的是this不是由它本身出现在何处来决定的。

而是由调用它的对象来决定的,可以简单的理解为。是谁调用了this,那么this便代表谁。比如在全局作用域中调用this。那么此时的this便代表着全局变量。

例:

console.log(this === window) 如上文说所的来分析,如是在全局作用域中。this则代表着全局变量。也就是window,那么事实是不是这样呢。运行上面的代码,输出true。证明this的却是window.

如果this是在一个对象中出现,那么正常情况下。this则代表该对象。

例:

 代码如下


var obj = {
   fn:function(){
      console.log(this === obj);
  }
}

obj.fn();//true弄明白了这两点,this的真相似乎已经浮出水面了。下面我们来看一个复杂点的例子。相信有很多人都会犯错,同时这也是一道经典的面试题。

 代码如下


var length = 20;
function fn(){
    console.log(this.length);
}

var o = {
length:10,
e:function (fn){
    fn();
   arguments[0]();
}
}

o.e(fn);相信有不少的同鞋会认为让面会输出 20,20; 也有少部分人认为是10,10; 或者20 10,10 20;

但是很遗憾,上面的答案全部错误。先不急着公布正确答案,我们来分析一下,看看在运行中this到底代表什么。

当运行o.e(fn);时,e中的this代表着o。因为是o调用了e。这点相信大家都没有疑问。

当进入e时。执行fn(); 此时的fn也就是参数传递进来的fn,由于函数名只是保存了一个指向函数的引用。所以此时e内部的fn与外面的fn是一模一样的。又因为函数内部的this是由函数的调用者决定的。所以此时fn内的this代表了window。这点相信当家也没有疑问。

当执行arguments[0]()时,由于arguments[0]是函数的第一个参数,等于fn。所以此时的函数也就等于外部的fn,理论上来说this也应该是等于window的。

似乎这么解释是合理的。 那么正确答案就应该是20,20.那么我又为何说上面的答案中没有一个是正确的呢。那是因为我们忽略了一点。那就是,arguments。

由于arguments[0]().相当与arguments.0(); 也就是说,正真调用fn的是arguments。所以函数内部的this应该是arguemnts,所以。this.length 等于参数的个数,也就是1.正确答案是20 1.

相信大家都明白了吧,那么下面我们就来看看是什么样的机制造就了this。

首先,当一个函数被运行时。他都会进入一个新的执行环境,就算是同一个函数两次调用,异或是函数自身递归调用,它们所进入的执行环境都是不同的。

下面就来看看,在JavaScript中各种this的使用方法有什么混乱之处?

    1、在HTML元素事件属性中inline方式使用this关键字: 

 代码如下

 // 可以在里面使用this

 ">division element

    我们一般比较常用的方法是在此使用:javascirpt: EventHandler(this),这样的形式。不过这里其实可以写任何合法的JavaScript语句,要是高兴在此定义个类也可以(不过将会是个内部类)。这里的原理是脚本引擎生成了一个div实例对象的匿名成员方法,而onclick指向这个方法。

    2、用DOM方式在事件处理函数中使用this关键字:

 代码如下

 division element
 <script language="javascript">
 var div = document.getElementById("elmtDiv");
 div.attachEvent("onclick", EventHandler);

 function EventHandler()
 {
    // 在此使用this
 }
 </script>

    这时的EventHandler()方法中的this关键字,指示的对象是IE的window对象。这是因为EventHandler只是一个普通的函数,对于attachEvent后,脚本引擎对它的调用和div对象本身没有任何的关系。同时你可以再看看EventHandler的caller属性,它是等于null的。如果我们要在这个方法中获得div对象引用,应该使用:this.event.srcElement。

    3、用DHTML方式在事件处理函数中使用this关键字:

 代码如下

 division element
 <script language="javascript">
 var div = document.getElementById("elmtDiv");
 div.onclick = function()
 {
    // 在此使用this
 };
 </script>

    这里的this关键字指示的内容是div元素对象实例,在脚本中使用DHTML方式直接为div.onclick赋值一个EventHandler的方法,等于为div对象实例添加一个成员方法。这种方式和第一种方法的区别是,第一种方法是使用HTML方式,而这里是DHTML方式,后者脚本解析引擎不会再生成匿名方法。

    4、类定义中使用this关键字:

 代码如下

  function JSClass()
  {
      var myName = "jsclass";
      this.m_Name = "JSClass";
  }

  JSClass.prototype.ToString = function()
  {
      alert(myName + ", " + this.m_Name);
  };

  var jc = new JSClass();
  jc.ToString();

    这是JavaScript模拟类定义中对this的使用,这个和其它的OO语言中的情况非常的相识。但是这里要求成员属性和方法必须使用this关键字来引用,运行上面的程序会被告知myName未定义。

 

    5、为脚本引擎内部对象添加原形方法中的this关键字:

 代码如下

  Function.prototype.GetName = function()
  {
      var fnName = this.toString();
      fnName = fnName.substr(0, fnName.indexOf("("));
      fnName = fnName.replace(/^function/, "");
      return fnName.replace(/(^s+)|(s+$)/g, "");
  }
  function foo(){}
  alert(foo.GetName());   

    这里的this指代的是被添加原形的类的实例,和4中类定义有些相似,没有什么太特别的地方。

    6、结合2&4,说一个比较迷惑的this关键字使用:

 代码如下

  function JSClass()
  {
      this.m_Text = "division element";
      this.m_Element = document.createElement("DIV");
      this.m_Element.innerHTML = this.m_Text;
       
      this.m_Element.attachEvent("onclick", this.ToString);
  }
  
  JSClass.prototype.Render = function()
  {
      document.body.appendChild(this.m_Element);
  }    

  JSClass.prototype.ToString = function()
  {
      alert(this.m_Text);
  };

  var jc = new JSClass();
  jc.Render();
  jc.ToString();

    我就说说结果,页面运行后会显示:"division element",确定后点击文字"division element",将会显示:"undefined"。

    7、CSS的expression表达式中使用this关键字:

 代码如下

 
     
         
                                  height: expression(this.parentElement.height);">
                  division element
         
     
 

    这里的this看作和1中的一样就可以了,它也是指代div元素对象实例本身。

    8、函数中的内部函数中使用this关键字:

 代码如下

  function OuterFoo()
  {
      this.Name = "Outer Name";
 
      function InnerFoo()
      {
          var Name = "Inner Name";
          alert(Name + ", " + this.Name);
      }
      return InnerFoo;
  }
  OuterFoo()();

本文来源:http://www.bbyears.com/asp/35357.html