javascript this用法小结


Posted in Javascript onDecember 19, 2008

this是面向对象语言中的一个重要概念,在JAVA,C#等大型语言中,this固定指向运行时的当前对象。但是在javascript中,由于 javascript的动态性(解释执行,当然也有简单的预编译过程),this的指向在运行时才确定。这个特性在给我们带来迷惑的同时也带来了编程上的 自由和灵活,结合apply(call)方法,可以使JS变得异常强大。
2.变化的this
在JavaScript中,this通常指向的是我们正在执行的函数本身,或者是指向该函数所属的对象(运行时)。当我们在页面中定义了函数 doSomething()的时候,它的owner是页面,或者是JavaScript中的window对象(或 global对象)。对于一个onclick属性,它为它所属的HTML元素所拥有,this应该指向该HTML元素。
2.1在几种常见场景中this的变化
函数示例
function doSomething ()
{
alert(this.navigator); //appCodeName
this.value = "I am from the Object constructor";
this.style.backgroundColor = "# 000000";
}
1. (A)作为普通函数直接调用时,this指向window对象.
2. (B)作为控件事件触发时
1) inline event registration 内联事件注册 .将事件直接写在HTML代码中(<element
onclick=”doSomething()”>), 此时this指向 window对象 。
2) Traditional event registration 传统事件注册 (DHTML方式).
形如 element.onclick = doSomething; 此时this指向 element对象
3) <element onclick=”doSomething(this)”>作为参数传递可以指向element
3. (C)作为对象使用时this指向当前对象。形如:new doSomething();
4. (D)使用apply 或者call方法时,this指向所传递的对象。
形如:var obj={}; doSomething.apply(obj,new Array(”nothing”); //thisàobj

下面我来阐述如何在事件处理中来使用this,之后我会附加一些this相关的例子。
Owner
接下来文章中我们将要讨论的问题是:在函数doSomething()中this所指的是什么?
Javascript代码
function doSomething() {
this.style.color = '#cc0000';
}
function doSomething() {
this.style.color = '#cc0000';
}
在JavaScript中,this通常指向的是我们正在执行的函数本身(译者注:用owner代表this所指向的内容),或者是,指向该函数所属的对象。当我们在页面中定义了函数doSomething()的时候,它的owner是页面,或者是JavaScript中的window对象(或 global对象)。对于一个onclick属性,它为它所属的HTML元素所拥有,this应该指向该HTML元素。
这种“所有权”就是JavaScript中面向对象的一种方式。在Objects as associative arrays中可以查看一些更多的信息。
javascript this用法小结 
如果我们在没有任何更多准备情况下执行doSomething(),this关键字会指向window,并且该函数试图改变window的 style.color。因为window并没有style对象,这个函数将非常不幸的运行失败,并产生JavaScript错误。
Copying
因此如果我们想充分利用this,我们不得不注意使用this的函数应该被正确的HTML元素所拥有。换句话说,我们应该复制这个函数到我们的onclick属性。Traditional event registration会关心它。
Javascript代码
element.onclick = doSomething;
element.onclick = doSomething;
这个函数被完整复制到onclick属性(现在成为了函数)。因此如果这个event handler被执行,this将指向HTML元素,并且该元素的颜色得以改变。
javascript this用法小结 
这种方法使得我们能够复制这个函数到多个event handler。每次this都将指向正确的HTML元素:
javascript this用法小结 
这样你就可以最大限度使用this。每当执行该函数,this所指向的HTML元素都正确响应事件,这些HTML元素拥有doSomething()的一个拷贝。
Referring
然而,如果你使用inline event registration(内联事件注册)
Javascript代码
<element onclick="doSomething()">
<element onclick="doSomething()">
你将不能拷贝该函数!反而这种差异是非常关键的。onclick属性并不包含实际的函数,仅仅是一个函数调用。
Javascript代码
doSomething();
doSomething();
因此,它将声明“转到doSomething()并且执行它”。当我们到达doSomething(),this关键字又重新指向了全局的window对象,函数返回错误信息。
javascript this用法小结 
The difference
如果你想使用this来指向HTML元素响应的事件,你必须确保this关键字被写在onclick属性里。只有在这种情况下它才指向event handler所注册的HTML元素。
Javascript代码
element.onclick = doSomething;
alert(element.onclick)
element.onclick = doSomething;
alert(element.onclick)
你将得到
Javascript代码
function doSomething() {
this.style.color = '#cc0000';
}
function doSomething() {
this.style.color = '#cc0000';
}
正如你所见,this关键字被展现在onclick函数中,因此它指向HTML元素。
但是如果执行
Javascript代码
<element onclick="doSomething()">
alert(element.onclick)
<element onclick="doSomething()">
alert(element.onclick)
你将得到
Javascript代码
function onclick() {
doSomething()
}
function onclick() {
doSomething()
}
这仅仅是到doSomething()函数的一个引用。this关键字并没有出现在onclick函数中,因此它不指向HTML元素。
例子--拷贝
下面的例子中,this被写入onclick函数里:
Javascript代码
element.onclick = doSomething
element.addEventListener('click', doSomething, false)
element.onclick = function() {this.style.color = '#cc0000';}
<element onclick="this.sytle.color = '#cc0000';">
element.onclick = doSomething
element.addEventListener('click', doSomething, false)
element.onclick = function() {this.style.color = '#cc0000';}
<element onclick="this.sytle.color = '#cc0000';">
例子--引用
下述情况中,this指向window:
Javascript代码
element.onclick = function() {doSomething()}
element.attachEvent('onclick', doSomething)
<element onclick="doSomething()">
element.onclick = function() {doSomething()}
element.attachEvent('onclick', doSomething)
<element onclick="doSomething()">
注意attachEvent()的出现。Microsoft event registration model最主要的弊端是attachEvent()创建了一个指向函数的引用,而不是复制它。因此有时不可能知道哪个HTML正在处理该事件。
组合使用
当使用内联事件注册时,你可以将this发送到函数以至于可以正常使用:
Javascript代码
<element onclick="doSomething(this)">
function doSomething(obj) {
//this出现在event handler中并被发送到函数
//obj指向HTML元素,因此可以这样:
obj.style.color = '#cc0000';
}

Javascript 相关文章推荐
JavaScript Base64编码和解码,实现URL参数传递。
Sep 18 Javascript
一些技巧性实用js代码小结
Oct 14 Javascript
javascript复制对象使用说明
Jun 28 Javascript
Jquery 复选框取值兼容FF和IE8(测试有效)
Oct 29 Javascript
JavaScript实现的圆形浮动标签云效果实例
Aug 06 Javascript
轻松学习jQuery插件EasyUI EasyUI创建RSS Feed阅读器
Nov 30 Javascript
Angular 根据 service 的状态更新 directive
Apr 03 Javascript
BootStrap实现响应式布局导航栏折叠隐藏效果(在小屏幕、手机屏幕浏览时自动折叠隐藏)
Nov 30 Javascript
Vim快速合并行及vim 将文件所有行合并到一行
Nov 27 Javascript
no-vnc和node.js实现web远程桌面的完整步骤
Aug 11 Javascript
TypeScript之调用栈的实现
Dec 31 Javascript
JS script脚本中async和defer区别详解
Jun 24 Javascript
js 提交和设置表单的值
Dec 19 #Javascript
Javascript select控件操作大全(新增、修改、删除、选中、清空、判断存在等)
Dec 19 #Javascript
简单通用的JS滑动门代码
Dec 19 #Javascript
比较全的JS checkbox全选、取消全选、删除功能代码
Dec 19 #Javascript
Javascript 获取LI里的内容
Dec 17 #Javascript
FLASH 广告之外的链接
Dec 16 #Javascript
用tip解决Ext列宽度不够的问题
Dec 13 #Javascript
You might like
要会喝咖啡也要会知道咖啡豆
2021/03/03 咖啡文化
在字符串中把网址改成超级链接
2006/10/09 PHP
php入门学习知识点七 PHP函数的基本应用
2011/07/14 PHP
php制作unicode解码工具(unicode编码转换器)代码分享
2013/12/24 PHP
php多种形式发送邮件(mail qmail邮件系统 phpmailer类)
2014/01/22 PHP
php打造智能化的柱状图程序,用于报表等
2015/06/19 PHP
学习php设计模式 php实现单例模式(singleton)
2015/12/07 PHP
PHP未登录自动跳转到登录页面
2016/12/21 PHP
彻底搞懂PHP 变量结构体
2017/10/11 PHP
laravel 输出最后执行sql 附:whereIn的使用方法
2019/10/10 PHP
用javascript关闭本窗口不弹出询问框的方法
2014/09/12 Javascript
jquery实现炫酷的叠加层自动切换特效
2015/02/01 Javascript
JavaScript中的Math.E属性使用详解
2015/06/12 Javascript
浅析JS异步加载进度条
2016/05/05 Javascript
js实现抽奖效果
2017/03/27 Javascript
详解如何让InstantClick兼容MathJax、百度统计等
2017/09/12 Javascript
js实现手机web图片左右滑动效果
2017/12/29 Javascript
jQuery实现图片上传预览效果功能完整实例【测试可用】
2018/05/28 jQuery
vuex的module模块用法示例
2018/11/12 Javascript
jQuery实现表格的增、删、改操作示例
2019/01/27 jQuery
小程序云开发实现数据库异步操作同步化
2019/05/18 Javascript
Vue实现数据请求拦截
2019/10/23 Javascript
详解JavaScript中new操作符的解析和实现
2020/09/04 Javascript
python实现自动登录人人网并访问最近来访者实例
2014/09/26 Python
python解析html提取数据,并生成word文档实例解析
2018/01/22 Python
Pytorch加载部分预训练模型的参数实例
2019/08/18 Python
Merchant 1948澳大利亚:新西兰领先的鞋类和靴子供应商
2018/03/24 全球购物
交通事故私了协议书
2014/04/16 职场文书
办公室主任岗位承诺书
2014/05/29 职场文书
2014光棍节单身联谊活动策划书
2014/10/10 职场文书
教师作风整改措施思想汇报
2014/10/12 职场文书
2015年学校安全工作总结
2015/04/22 职场文书
2015年小学英语教师工作总结
2015/05/12 职场文书
2016年寒假社会实践活动心得体会
2015/10/09 职场文书
Nginx使用X-Accel-Redirect实现静态文件下载的统计、鉴权、防盗链、限速等
2021/04/04 Servers
golang 在windows中设置环境变量的操作
2021/04/29 Golang