• javascript this关键字


    javascript最重要的关键字之一是this。但是如果你不了解它的工作原理使用起来就会很困难。

    下面我将介绍在事件处理中如何运用它。以后我会增加this的其他用途。

    所有者

    这篇文章将要讨论的问题是:在函数doSomething()this到底指向谁?

    function doSomething(){
       
    this.style.color ='#cc0000';
    }

    在javascript中,this始终指向我们正在执行的这个函数的“所有者”,或者更确切地说,函数是哪个对象的方法this就指向哪个对象。当我们在页面中定义函数doSomething()的时候,他的所有者就是这个页面,或者说javascript的window对象(或全局对象)。而一个onclick属性的所有者是它所在的HTML元素。

    这种“所属关系”是javascript的面向对象特性造成的,欲了解更多信息请阅读这篇对象亦是关联数组

    ------------ window --------------------------------------
    |                                          /\           |
    |                                           |            |
    |                                          this          |
    |   ----------------                        |            |
    |   |   HTML 元素   |<--this         -----------------  |
    |   ----------------      |           | doSomething()|  |
    |               |         |           -----------------  |
    |          --------------------                          |
    |          |   onclick 属性    |                          |
    |          --------------------                          |
    |                                                        |
    ----------------------------------------------------------


    如果我们直接执行doSomething(),那么this关键字指向window,并且函数会去改变window对象的style.color,由于window对象没有style属性,这个函数会执行失败,并产生js错误。

    拷贝

    如果我们要合理地运用this就必须确保使用它的函数为正确的HTML元素所拥有,或换一种说法,我们必须把函数拷贝到onclick属性上,传统的事件绑定模型很好地处理了这个问题。

    element.onclick = doSomething;

    函数被完整地拷贝到了onclick属性上(现在成了一个方法),所以当事件处理函数被执行的时候this指向HTML元素并且它的color会被改变。

    ------------ window --------------------------------------
    |                                                        |
    |                                                        |
    |                                                        |
    |   ----------------                                     |
    |   |    HTML元素   |<--this         -----------------  |
    |   ----------------      |           | doSomething()|  |
    |               |         |           -----------------  |
    |          -----------------------          |            |
    |          |doSomething()的一份拷贝|  <--  拷贝函数         |
    |          -----------------------                       |
    |                                                        |
    ----------------------------------------------------------


    这里有个小技巧是我们可以把函数拷贝到多个事件处理器上,每次this都能指向正确地HTML元素:

    ------------ window --------------------------------------
    |                                                        |
    |                                                        |
    |                                                        |
    |   ----------------                                     |
    |   |   HTML元素    |<--this         -----------------  |
    |   ----------------      |           | doSomething()|  |
    |               |         |           -----------------  |
    |          -----------------------          |            |
    |          |doSomething()的一份拷贝|  <--  拷贝函数         |
    |          -----------------------          |            |
    |                                           |            |
    |   -----------------------                 |            |
    |   |    另一个HTML元素     |<--this        |            |
    |   -----------------------     |           |            |
    |               |               |           |            |
    |          -----------------------          |            |
    |          |doSomething()的一份拷贝|  <--  拷贝函数         |
    |          -----------------------                       |
    |                                                        |
    ----------------------------------------------------------

    这样才是比较充分地使用this,每次函数被执行的时候this都指向触发了这个事件的HTML元素,这个HTML元素“拥有”了doSomething()的一份拷贝。

    调用

    然而如果你使用行内事件绑定方式

    <element onclick="doSomething()">

    你没有拷贝函数!而是调用了这个函数。其中的区别是很关键的。这里的onclick属性并没有包含任何实际的函数,而只是一个触发了这个函数:

    doSomething();

    他只是说了句“找到doSomething()并执行它”,当我们找到doSomething()的时候this关键字再一次指向了全局的window对象,并且函数会返回错误提示。(chrome的this指向的正是window)

    ------------ window --------------------------------------
    |                                          /\           |
    |                                           |            |
    |                                          this          |
    |   ----------------                        |            |
    |   |    HTML元素   |<--this         -----------------  |
    |   ----------------      |           | doSomething()|  |
    |               |         |           -----------------  |
    |          -----------------------         /\           |
    |          |找到doSomething()    |          |            |
    |          |并执行它             |----   对函数的调用     |
    |          -----------------------                       |
    |                                                        |
    ----------------------------------------------------------

    区别

    如果你想通过this来获得触发了这个事件的HTML元素,就必须确保this关键字确实被写入到了onclick属性里面,只有这种情况下它才会指向该函数所绑定到的HTML元素。所以如果你测试下面这段

    element.onclick = doSomething;
    alert
    (element.onclick)

    你将得到:

    function doSomething()
    {
           
    this.style.color ='#cc0000';
    }

    可以看到,this关键字出现在onclick方法里面,因此它会指向HTML元素

    但是如果你测试以下这段:

    <element onclick="doSomething()">
    alert
    (element.onclick)

    会得到

    function onclick()
    {
            doSomething
    ()
    }

    这只是一个对函数doSomething()的调用,this关键字并没有出现在onclick方法里面,所以它不会指向HTML元素。

    例子——拷贝

    在下面的情况下this会写入onclick方法内:

    element.onclick = doSomething
    element
    .addEventListener('click',doSomething,false)
    element
    .onclick =function(){this.style.color ='#cc0000';}
    <element onclick="this.style.color = '#cc0000';">

    例子——调用

    下面这些情况this指向window:

    element.onclick =function(){doSomething()}
    element
    .attachEvent('onclick',doSomething) (ie报错无法设置属性“color”的值: 对象为 null 或未定义)
    <element onclick="doSomething()">

    注意这里出现了attachEvent()微软事件绑定模型的一个严重的缺点attachEvent()只建立了对函数的调用但没有拷贝。所以有些时候我们无法知道是哪个HTML元素触发了这个事件。

    二者结合

    当使用行内事件绑定方式时也可以把this传给函数,使你仍然可以在函数内部使用它:

    <element onclick="doSomething(this)">

    function doSomething(obj){
    // this出现在了事件处理器内并且传给了函数
    // obj现在指向HTML元素,所以你可以做以下操作
    obj
    .style.color ='#cc0000';
    }

    本文翻译自PPK的The this keyword

    via:http://biaoge.me/2010/01/289

     有时出现错误:

    Object [object DOMWindow] has no method ‘attachEvent’

    This error occurs when trying bind an event, using window.attachEvent as a function, which only works in Internet Explorer.

    Your code might look something like this:

    var myFunction = function(){
      alert("foo");
    }
    
    window.attachEvent("onclick", myFunction);
    

    To fix this, use the following code (remember to remove “on” from “onclick” etc):

    var myFunction = function(){
      alert("foo");
    }
    
    window.addEventListener("click", myFunction,false);
    要注意自己的代码到底运行在哪个浏览器上。

  • 相关阅读:
    流程控制值while 循环
    编程语言和变量
    计算机1&操作系统硬件
    使用 Cygwin 在 Windows 中使用 Linux 命令
    windows系统安装mysql及导库
    linux报错 OSError: [Errno 24] Too many open files
    python3报错ModuleNotFoundError: No module named 'Queue'
    mac版本intellij idea默认快捷键
    mysql初设密码及允许远程访问
    PyCharm 图标 c、m、F、f、v、p 分别代表什么含义?
  • 原文地址:https://www.cnblogs.com/youxin/p/2726893.html
Copyright © 2020-2023  润新知