JavaScript中的作用域

来源:Realazy 作者:Realazy 2007-11-20 出处:pcdog.com

解决方案  
上一页 1 2 3 4 下一页 

this? 那是虾米?

每一个运行上下文除了建立一个作用域链外,还提供一个名为this的关键字。它的普遍用法是,this作为一个独特的功能,为邻里们提供一个可访问到它的途径。

但总是依赖于这个行为并不可靠:取决于我们如何进入一个特定邻居的具体情况,this表示的完全可能是其他东西。事实上,我们如何进去邻居家本身,通常恰恰就是this所指。有四种情形值得特别注意:

  1. 呼叫对象的方法

    在经典的面向对象编程中,我们需要识别和引用当前对象。this极好地扮演了这个角色,为我们的对象提供了自我查找的能力,并指向它们本身的属性。

    <script type="text/javascript">
      var deep_thought = {
       the_answer: 42,
       ask_question: function () {
        return this.the_answer;
       }
      };

      var the_meaning = deep_thought.ask_question();
    </script>



    这个例子建立了一个名为deep_thought的对象,设置其属性 the_answer为42,并创建了一个名为ask_question 的方法(method)。当deep_thought.ask_question()执行时, JavaScript为函数的呼叫建立了一个运行上下文,通过”.“运算符把this指向被引用的对象,在此是deep_thought这个对象。之后这个方法就可以通过this在镜子中找到它自身的属性,返回保存在 this.the_answer中的值:42。

  2. 构造函数

    类似地,当定义一个作为构造器的使用new关键字的函数时,this可以用来引用刚创建的对象。让我们重写一个能反映这个情形的例子:

    <script type="text/javascript">
      function BigComputer(answer) {
       this.the_answer = answer;
       this.ask_question = function () {
        return this.the_answer;
       }
      }

      var deep_thought = new BigComputer(42);
      var the_meaning = deep_thought.ask_question();
    </script>



    我们编写一个函数来创建BigComputer对象,而不是直白地创建 deep_thought对象,并通过new关键字实例化deep_thought为一个实例变量。当new BigComputer()被执行,后台透明地创建了一个崭新的对象。呼叫BigComputer后,它的this关键字被设置为指向新对象的引用。这个函数可以在this上设置属性和方法,最终它会在BigComputer执行后透明地返回。

    尽管如此,需要注意的是,那个deep_thought.the_question()依然可以像从前一样执行。那这里发生了什么事?为何this在the_question内与BigComputer内会有所不同?简单地说,我们是通过new进入BigComputer的,所以this表示“新(new)的对象”。在另一方面,我们通过 deep_thought进入the_question,所以当我们执行该方法时,this表示 “deep_thought所引用的对象”。this并不像其他的变量一样从作用域链中读取,而是在上下文的基础上,在上下文中重置。

  3. 函数呼叫

    假如没有任何相关对象的奇幻东西,我们只是呼叫一个普通的、常见的函数,在这种情形下this表示的又是什么呢?

    <script type="text/javascript">
      function test_this() {
       return this;
      }
      var i_wonder_what_this_is = test_this();
    </script>

    在这样的场合,我们并不通过new来提供上下文,也不会以某种对象形式在背后偷偷提供上下文。在此, this默认下尽可能引用最全局的东西:对于网页来说,这就是 window对象。

  4. 事件处理函数

    比普通函数的呼叫更复杂的状况,先假设我们使用函数去处理的是一个onclick事件。当事件触发我们的函数运行,此处的this表示的是什么呢?不凑巧,这个问题不会有简单的答案。

    如果我们写的是行内(inline)事件处理函数,this引用的是全局window对象:

    <script type="text/javascript">
      function click_handler() {
       alert(this); // 弹出 window 对象
      }
    </script>
     ...
    <button id='thebutton' onclick='click_handler()'>Click me!</button>

    但是,如果我们通过JavaScript来添加事件处理函数,this引用的是生成该事件的DOM元素。(注意:此处的事件处理非常简洁和易于阅读,但其他的就别有洞天了。请使用 真正的addEvent函数 取而代之):

    <script type="text/javascript">
      function click_handler() {
       alert(this); // 弹出按钮的DOM节点
      }

      function addhandler() {
       document.getElementById('thebutton').onclick = click_handler;
      }

      window.onload = addhandler;
    </script>
     ...
    <button id='thebutton'>Click me!</button>



上一页 1 2 3 4 下一页 
上一篇:jQuery技巧总结
下一篇:javascript实现划词标记+划词搜索功能