【简译】this关键字

文章翻译自此文章

javascript中最有威力的关键字之一就是this。不幸的是,如果你不彻底了解它是如何工作的话,它会很难使用。下面我介绍了如何在event handling。稍后,我会加入一些this的其他用法。

所有者

接下来我们将要讨论的问题是:在doSomething函数中,this指的是什么?

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

在javascript中,this始终指向我们正在执行的函数的“所有者”,更精确地说,指向把这个函数作为方法的对象。当我们在一个页面定义我们忠实的doSomething函数,他的所有者是这个页面,更精确的说,是javascript的window对象(或者全局对象)。一个onclick属性,被它属于的HTML元素所拥有。这种“所有权”是javascript面向对象方式的结果。通过 对象作为关联数组这个页面了解更多。

如果我们直接执行doSomething函数,this指向window,这个函数将尝试改变window的style.color,因为window没有style对象(似乎属性更好,但原文如此),这函数将失败并导致一个javascript错误。

复制

所以,如果我们想要充分利用this,我们就要小心的让使用了这个this的函数被正确的HTML元素“拥有”。换句话说,我们不得不将函数拷贝给onclick属性传统的事件注册照顾好了这个:

element.onclick = doSomething;

这个函数被整体拷贝给了onclick属性(它这样就变成了一个方法)因此,如果event handler 被执行,this指向这个HTML元素同时他的color将会改变。

我们当然可以用这种方式拷贝这个函数给几个event handler。每次this将指向正确的HTML元素。

这样你可以最大限度的利用this。每次函数被调用,this指向的HTML元素正在正确的处理事件,HTML元素“拥有”doSomething函数的拷贝。

引用

然而,如果你使用了内联事件注册(inline event registration)

<element onclick="doSomething()">

你这样是没有拷贝这个函数的!相反,你引用了它,引用和拷贝这两者之间的区别是至关重要的。onclick属性没有包含真正的函数,仅仅是一个函数调用:

doSomething();所以,这个表达式的意思是“转到doSomething()并执行它。”当我们到达doSomething(),this关键字有一次指向全局window对象同时函数返回错误消息。

区别

如果你想为了访问那些正在处理事件的HTML元素(accessing the HTML element that is handling the event)而使用this,你必须确保this关键字已经整整的写入了onclick属性中。只有在这种情况,this才指向那些注册了event handler 的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)
//addEventListener是W3C标准的注册方式
element.onclick = function () {this.style.color = ‘#cc0000‘;}
<element onclick="this.style.color = ‘#cc0000‘;">

引用的例子

下面的例子this指向window:

element.onclick = function () {doSomething()}
element.attachEvent(‘onclick‘,doSomething)
//这是IE的事件注册方式注意和上面拷贝的不同
<element onclick="doSomething()">

注意attachEvent()的存在,微软事件注册模型的主要缺点就是attachEvent()生成的是函数的引用而不是宝贝这个函数。因此有时候了解那个HTML当前正在处理时间是不可能的。

混合

当使用内联事件注册你一可以传递this给这个函数,这样你就仍然可以使用它:

<element onclick="doSomething(this)">

function doSomething(obj) {
    // this is present in the event handler and is sent to the function
    // obj now refers to the HTML element, so we can do
    obj.style.color = ‘#cc0000‘;
}

后记:

这个作者关于几个事件注册方式的阐述也很值得一看:早期事件注册 ,传统事件注册高级事件注册。同时这篇介绍函数调用以及this也是相当值得一看的,这篇是单独介绍this。

【简译】this关键字

时间: 2025-01-10 08:59:44

【简译】this关键字的相关文章

【简译】jQuery对象的奥秘:基础介绍

本文翻译自此文章 你有没有遇到过类似$(".cta").click(function(){})这样的JavaScript代码并且在想“$('#x')是什么”?如果这些对你想天书一样,请往下读.如果你认为这些代码不可能是真的,请浏览一些jQuery例子,他们都是这种结构. 这篇文章覆盖了像下面一样吓人的代码片段中涉及的关键概念.我们以一个长例子开始,这个长例子是基于一个让一个正方形运动的简单例子(a simple example of animating a square).你可能不需要

Unity性能优化(2)-官方文档简译

本文是Unity官方教程,性能优化系列的第二篇<Diagnosing performance problems using the Profiler window>的简单翻译. 简介 如果游戏运行缓慢,卡顿,我们知道游戏存在性能问题.在我们尝试解决问题前,需要先知道引起问题的原因.不同问题需要不同的解决方案.如果我们靠猜测或者其他项目的经验去解决问题,那么我们可能会浪费很多时间,甚至使得问题更严重. 这时我们需要性能分析,性能分析程序测量游戏运行时的各个方面性能.通过性能分析工具,我们能够透过

简析clone关键字与__clone()方法

一.对象复制 1.需求 在多数情况下,我们并不需要完全复制一个对象来获得其中属性.但有一个情况下确实需要:如果你有一个 GTK 窗口对象,该对象持有窗口相关的资源.你可能会想复制一个新的窗口,保持所有属性与原来的窗口相同,但必须是一个新的对象(因为如果不是新的对象,那么一个窗口中的改变就会影响到另一个窗口). 还有一种情况,如果对象 A 中保存着对象 B 的引用,当你复制对象 A 时,你想其中使用的对象不再是对象 B 而是 B 的一个副本,那么你必须得到对象 A 的一个副本 2.基本概念 有的时

【Android API Guides简译(四)】使用Service还是使用线程?

一个服务是一个组件,这个组件可以在Android后台运行,即使你的这个应用被关闭,它依然在运行.所以说只有你需要一个和当前程序无关的后台程序时,才去创建它. 而如果你只是想让你的App在主线程外工作,而且操作限定在当前程序中时,只需要在在里面创建另一个线程. 比如你只是想在你的Activity在运行时,放一首音乐,那么你应该在onCreat()方法里创建另一个线程,在onStart()里开始线程,在onStop()里结束这个线程,同时你也要考虑到使用AsyncTask orHandlerThre

【Android API Guides 简译(三)】Data Storage--Storage Options

Android提供了几种永久储存手机数据的选项,而我们选择存储的方式依据于我们存储的不同的特定需求,比如你的数据是否需要只对自己公开,数据是否可以被其他应用得到或者你想要储存多大的数据. 数据存储的方式如下: Shared Preferences 通过xml类型的键值对,存储私密的原始数据. Internal Storage 内部存储 通过手机内存存储私密数据 External Storage 外部存储 在设备外部共享里存储公开的数据 SQLite Databases Android 原生内部数

【Android API Guides 简译(一)】App Resourses--Overview

将数据与程序分开的原因,表面是为了独立的管理数据,深层原因是使App兼容不同的环境即使你的数据支持不同语言或者不同屏幕大小的特殊设备.这是非常且越来越重要的! 对于各种各样的资源,我们统一分成两种: 默认资源和针对不同环境的备选资源 举个例子,默认资源存放在res/layout/ directory下,针对于横摆方向的设备的备选资源存放在res/layout-land/ directory(横摆方向的设备的具体方式见图).当只有默认资源时,见图1.当设置了备选资源时,见图二,Android系统会

OC字符串之NSString.h方法简译

@interface NSString : NSObject <NSCopying, NSMutableCopying, NSSecureCoding> @property (readonly) NSUInteger length;//获得字符串的长度 - (unichar)characterAtIndex:(NSUInteger)index;//返回在字符串中的某个位置的字符,参数索引 - (instancetype)init NS_DESIGNATED_INITIALIZER;//构造方法

Unity性能优化(1)-官方文档简译

本文是Unity官方教程,性能优化系列的第一篇<The Profiler window>的简单翻译. 简介 性能分析工具可以给我们提供游戏性能表现的详细信息.如果我们的游戏存在性能问题,如低帧率或者高内存占用,性能分析工具可以帮助我们发现问题的起因,并协助我们解决问题. Profiler工具是Unity内置的强大的性能分析工具,本文介绍如何使用它.当我们阅读完本文,并且熟悉Profiler的界面和功能时,我们可以继续学习怎么使用它对不同类型的性能问题进行诊断. Profiler可以给我们提供,

The story behind _references.js 简译一下

_references.js背后的故事 _references.js是在VS的WEB项目中,提供智能提示的关键技术. 在VS2010发布之后,作者还是ASP.NET小组成员时,小组想把js编辑器的功能迁移到一个新的"客户端平台小组".这个小组将要为VS2012创建一个全新的,现代的js编辑器,另一层目的就是为即将到来的Win8 App提供HTML/JS开发支持.而原来的js编辑器从vs中剥离,但它却在webMatrix中重生,包括之后的开发及更新. 既然要开发新的编辑器,正好是重新设计