`
boin
  • 浏览: 34710 次
社区版块
存档分类
最新评论

The this Keyword in JavaScript

阅读更多
JavaScript this 关键字

翻译自PPK Book

this 是 JavaScript 中很强大的关键字之一。但是不幸的是,如果你不能完全明白它的特征和用法的话,你可能会在使用的时候碰到很多问题。

本文从事件响应的列子开始,来试图说明this关键字的用法和一些知识。

Owner(宿主)

在余下的篇幅中,我们会一直围绕着一个函数来讨论,doSomething(),在这个方法中,this到底指向什么?
function doSomething() {
   this.style.color = '#cc0000';
}

在JavaScript中this是始终指向正在被执行的方法的“owner”(宿主),或者是包含这个方法的对象本身。如果我们在某个页面中定义了一个doSomething()函数,那么这个方法的owner则是这个页面,即当前window对象或JavaScript的全局对象。举个例子来说:一个“onclick”属性是被包含于某个HTML元素中的,那这个属性的owner就是这个HTML元素。

ownership(存在关系)是JavaScript的面向对象模型的产物 。实际上对象都是以关联数组的形式来组织的。

------------ window --------------------------------------
|                                          / \           |
|                                           |            |
|                                          this          |
|   ----------------                        |            |
|   | HTML element | <-- this         -----------------  |
|   ----------------      |           | doSomething() |  |
|               |         |           -----------------  |
|          --------------------                          |
|          | onclick property |                          |
|          --------------------                          |
|                                                        |
----------------------------------------------------------


当我们不做任何准备直接执行doSomething()函数的话,此时this是指向window对象的,然后方法试图改变window对象的style.color,当然,此时window对象并不存在这样一个style对象,所以该函数执行失败,并抛出一个JavaScript错误。

Copying(拷贝)

如果我们想要这个函数正常工作的话,我们就要让这个函数被包含在正确的HTML对象中。
换句话来说,就是我们要把这个函数“拷贝”到onclick属性上。然后传统的事件注册模型会自动处理余下的工作。
element.onclick = doSomething;

这段代码把整个doSomething()函数拷贝到了某个HTML元素的onclick属性上(然后这个函数变成了一个成员方法)这时再单击该HTML元素时,事件响应会自动调用onclick属性绑定的方法,此时this已经指向了该HTML对象,然后方法顺利执行,改变了element元素的原色。
------------ window --------------------------------------
|                                                        |
|                                                        |
|                                                        |
|   ----------------                                     |
|   | HTML element | <-- this         -----------------  |
|   ----------------      |           | doSomething() |  |
|               |         |           -----------------  |
|          -----------------------          |            |
|          |copy of doSomething()|  <-- copy function    |
|          -----------------------                       |
|                                                        |
----------------------------------------------------------

我们可以把这个函数拷贝到很多个HTML对象的事件响应函数中。然后每次运行的时候this就会指向正确的HTML对象。
------------ window --------------------------------------
|                                                        |
|                                                        |
|                                                        |
|   ----------------                                     |
|   | HTML element | <-- this         -----------------  |
|   ----------------      |           | doSomething() |  |
|               |         |           -----------------  |
|          -----------------------          |            |
|          |copy of doSomething()|  <-- copy function    |
|          -----------------------          |            |
|                                           |            |
|   -----------------------                 |            |
|   | another HTML element| <-- this        |            |
|   -----------------------     |           |            |
|               |               |           |            |
|          -----------------------          |            |
|          |copy of doSomething()|  <-- copy function    |
|          -----------------------                       |
|                                                        |
----------------------------------------------------------

做完所有拷贝后,当函数被执行时,this就被自动指向到正确的响应这个事件的HTML对象上了,此时该HTML对象就包含了doSomething()这个函数的拷贝。

Referring(引用)
你还可以使用inline(内联)的方式来绑定这个函数,即在HTML文档中对HTML元素制定onclick属性。
<element onclick="doSomething()">

记住,此时你并没有拷贝这个函数!你只是指向了这个函数,这个差异是很不容忽视的。这时onclick属性并没有包含这个方法,只是包含了对这个方法的一个调用。
doSomething();

此时当元素被单击时,代码的动作是“找到doSomething()方法,然后执行”。然后当我们找到并执行doSomething()方法时,this又被指向到了全局window对象,函数就会产生错误。
------------ window --------------------------------------
|                                          / \           |
|                                           |            |
|                                          this          |
|   ----------------                        |            |
|   | HTML element | <-- this         -----------------  |
|   ----------------      |           | doSomething() |  |
|               |         |           -----------------  |
|          -----------------------         / \           |
|          | go to doSomething() |          |            |
|          | and execute it      | ---- reference to     |
|          -----------------------       function        |
|                                                        |
----------------------------------------------------------

The difference(区别)

如果你要在事件响应中用this来访问HTML元素的话,你就必须保证this关键字已经写入到了onclick属性中。只有这样才能让this正确的指向HTML对象。所以你执行以下代码时:
element.onclick = doSomething;
alert(element.onclick)

你会得到
function doSomething()
{
	this.style.color = '#cc0000';
}

就像alert的结果所展示的,this关键字已经存在于onclick方法中了,于是它就指向到了该HTML元素。

如果这样做:
<element onclick="doSomething()">
alert(element.onclick)

你会得到
function onclick()
{
	doSomething()
}

这只是一个包含doSomething()函数的调用,this关键字并不存在于onclick方法中,当然也不会指向HTML对象。

示例 - copying

下列情形中,this已经被写入了onclick方法:
element.onclick = doSomething
element.addEventListener('click',doSomething,false)
element.onclick = function () {this.style.color = '#cc0000';}
<element onclick="this.style.color = '#cc0000';">

示例 - referring
下列情形中,this指向的是window对象:
element.onclick = function () {doSomething()}
element.attachEvent('onclick',doSomething)
<element onclick="doSomething()">

注意attachEvent()这个方法。微软事件注册模型的主要缺点是attachEvent()只是创建一个函数的引用,而并没有拷贝函数。因此,有些时候它是完全不知道目前的事件是绑定在哪个HTML对象的。

Combination(结合)

当你使用内联方式注册事件时,你可以指定this引用作为参数传递给响应方法。
<element onclick="doSomething(this)">
function doSomething(obj) {
	// this是存在于这个方法中的,只不过名字变成了obj
	// obj此时就指向了正确的HTML对象,然后我们就可以继续操作了
	obj.style.color = '#cc0000';
}
分享到:
评论

相关推荐

    JavaScript in 10 Minutes

    3. **Meaning of This**: Discusses the behavior of the `this` keyword in different contexts, including how it behaves differently inside a function compared to when used outside a function. - **Eta ...

    Secrets of the JavaScript Ninja, 2nd Edition

    They inherit the `this` value from the enclosing context, eliminating common issues related to the `this` keyword in traditional function expressions. For example: ```javascript const values = [0, 3...

    Learn by Example: JavaScript for Front-End and Mobile App Development

    This book aims to take someone completely new...The this keyword Get elements from the DOM Building your first mobile app Becoming an app developer Deploying your app to the Android and iTunes app stores

    Pro JavaScript Techniques (2nd)

    You will learn about the 'this' keyword, as well as new object tools. You will be able to create reusable code with encapsulation, overloading and inheritance. The most recent techniques for debugging...

    使用JSDoc建立JavaScript代码的文档

    This function is assigned in the class constructor rather than using the prototype keyword. * @returns The Person's name * @type String */ this.getName = function() { return name; } } /** * ...

    用户画像推荐系统springboot设计和实现 计算机专业.pdf

    In this thesis, the user's search history serves as the foundation. Based on the characteristics of news, keywords are extracted as tags. Each search record contributes to identifying the user's ...

    php.ini-development

    sign, or by using the None keyword: ; foo = ; sets foo to an empty string ; foo = None ; sets foo to an empty string ; foo = "None" ; sets foo to the string 'None' ; If you use constants in your ...

    JScript Language Reference

    Welcome to the JScript Language Reference &lt;br&gt;These handy blocks of information will help you explore the many different parts of JScript...language listed alphabetically under the Alphabetic Keyword List....

    Kotlin - Kotlin Language Documentation 2.0.0

    - **JavaScript Applications:** Kotlin/JS enables you to compile Kotlin to JavaScript, which can run in browsers or Node.js. ##### Is Anything Missing? If you encounter any issues or feel that ...

    分页-SearchLibrary-master

    The library is further meant to assist with keyword searches on the data. This allows users to search for a particular record by name, for example. 已知的问题 In the search field, we do not get any ...

    bunnyhop:基于amqp构建的可插拔微服务消息传递框架

    Here we are not passing in options so it uses the defaults. Notice there is no new keyword. */ const bus = BunnyHop ( 'user' ) // This goes out to every service subscribed to 'event.user.created'. // ...

    freemarker总结

    &lt;#assign mail="jsmith@other.com" in my&gt; ${my.mail} l 输出结果: jsmith@acme.com jsmith@other.com l 数据模型中的变量任何地方都可见,也包括不同的名字空间,下面是修改的库: &lt;p&gt;Copyright ...

Global site tag (gtag.js) - Google Analytics