1. 概述
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”); //thisobj
2.2 this 指向分析
1 A场景。
直接调用的情况下,doSomething的运行时拥有者是window对象,因此this指向window
图示:
图1:A场景
2 B场景。
1)Traditional Event Registration
当我们要让函数中的this指向当前HTMLELEMENT时,可这样写
element.onclick = doSomething;
doSomething的引用(地址)赋给了element的onclick属性(这样就成为了函数)。此时
doSomething运行时拥有者(owner)就变成了element,this便指向了element。
图示:
图2: B场景 Traditional Event Registration
进行批量添加事件时,this均可正确指向。
图示:
图3: 多次Traditonal Event Registration
2) Inline Event Registration
形如 <element onclick=”doSomething()”>
图示:
图4:B场景 Inline Event Registration
这两种注册方式的区别是
element.onclick = doSomething;
alert(element.onclick)
可以得到
function doSomething() {
alert(this.navigator); //appCodeName
this.value = "I am from the Object constructor";
this.style.backgroundColor = "# 000000";
}
可以看到this关键字被展现在onclick函数中,它指向HTML元素。
如果执行
<element onclick="doSomething()">
al ert(element.onclick)
可以得到 :
function onclick(){
doSomething();
}
这仅仅是对doSomething()函数的一次调用,而doShomething的拥有者是window,因此 doSomething内的this指向window对象(啰嗦哦…….).
3 . C场景
具体内部细节不太了解,不知道是否可以这样理解
new doSomething(…..)
约等同于
var tempObj = {}; doSomething.apply(obj,new Array());
这样tempObj 可以得到doSomething内所定义的属性和方法,但是对 于 doSomething.prototype上的属性方法无法得到-_-!!
4 D场景
不懂…..
完了
不专业,比较浅显,想不出几个专有名词,郁闷~
PS 1:好多内容是copy的(*_*!),对图中表达有点疑意。图上多次写出 copy of function ,按照字面理解是函数对象的拷贝,我认为实际上是一个引用拷贝,对象拷贝是不可能的,如果是这样的话,每次添加事件都会拷贝一次对象,这显然不妥。
PS 2: 因为this指向在运行时才确定,我们经常碰到一个问题,当给一个DOM对象添加事件后,我们希望this指向一个指定对象,而非DOM对象本身,如下例。
<input type="button" id='btn' />
<script language="javascript">function btnObj(id)
{
this.disabled = true;
this.btn=document.getElementById(id);
/*
this.btn.onclick = btnOnclick ;
假如我们这样写,this会指向DOM对象,btnOnclick执行过程会报错
因为DOM btn并没有一个btn属性
*/
//通过这种方式可以解决这个问题[有些情况也可用tempThis = this这种形式]
this.btn.onclick = passHandler(this,btnOnclick);}function btnOnclick()
{
//如果this是DOM对象,这里就会报错,因为没有btn属性
this.btn.disabled = this.disabled;
}
function passHandler(obj,fun,arg)
{
return function(){
//if(!arg) {var arg = [];}
return fun.apply(obj,(arg?arg:[]));
}
}
new btnObj(”btn”);
</script>
分享到:
相关推荐
但是在javascript中,由于 javascript的动态性(解释执行,当然也有简单的预编译过程),this的指向在运行时才确定。这个特性在给我们带来迷惑的同时也带来了编程上的 自由和灵活,结合apply(call)方法,可以使JS变...
本篇文章主要是对javascript中的self和this用法进行了详细的总结介绍,需要的朋友可以过来参考下,希望对大家有所帮助
java中this&super的用法小结.doc
主要介绍了JavaScript中的this基本问题,结合实例形式总结分析了JavaScript中this的功能、常见用法与操作注意事项,需要的朋友可以参考下
break,continue和return这三个语句的用法新手们经常弄混淆,至少在我学习c语言的时候经常把它们的用法给搞错。不过现在好了,我已彻底搞清楚它们之间的用法
不用getURL和fsCommand方法 flash使用的actionscript跟javascript是非常相通的,下面描述如何互相调用函数: 1:javascript调用flash中的函数 在flash的脚本中增加 import flash.external.ExternalInterface;...
第一部分 深入理解DOM脚本编程 第1章 遵循最佳实践 1.1 不唐突和渐进增强 1.2 让JavaScript运行起来 1.2.1 把行为从结构中分离出来 1.2.2 不要版本检测 ... 12.9 小结
本文实例讲述了JavaScript创建对象方法。分享给大家供大家参考,具体如下: 最简单的方式就是创建一个Object对象,并为其添加属性和方法。 //示例代码 var person=new Object() person.name=yumi person.age=18 ...
本文实例讲述了JavaScript类的继承方法。分享给大家供大家参考,具体如下: 在JavaScript 里,被继承的函数称为超类型(父类,基类也行,其他语言叫法),继承的函数称为子类型(子类,派生类)。继承也有之前问题,比如...
this在javascript中已经相当灵活,把它放到React中给我们的选择就更加困惑了。下面一起来看看React this的5种绑定方法。 1.使用React.createClass 如果你使用的是React 15及以下的版本,你可能使用过React....
最近在看JavaScript设计模式,其中有一些巧妙的函数。所以将部分修改后记录在此,顺便加上自己写出的一些好玩的函数。方便大家和自己以后使用。下面来一起看看。 一、apply实现call Function.prototype.call = ...
在.Net中可以使用clone()来实现原型法 原型法的主要思想是,现在有1个类A,我想要创建一个类B,这个类是以A为原型的,并且能进行扩展。我们称B的原型为A。 2 javascript的方法可以分为三类: a -> 类方法 b -> 对象方法...
在jquery中,extend其实在做插件时还是用的比较多的,今天同时小结jquery和ext js中 的extend用法,先来看jquery中的。 1) extend(dest,src1,src2,src3…); 代码如下: var start = { id: 123, count: 41, desc: ...
第一部分 深入理解DOM脚本编程 第1章 遵循最佳实践 1.1 不唐突和渐进增强 1.2 让JavaScript运行起来 1.2.1 把行为从结构中分离出来 1.2.2 不要版本检测 ... 12.9 小结
第一部分 深入理解DOM脚本编程 第1章 遵循最佳实践 1.1 不唐突和渐进增强 1.2 让JavaScript运行起来 1.2.1 把行为从结构中分离出来 1.2.2 不要版本检测 ... 12.9 小结
第一种方法:cookie操作类,代码封装了,下面也有使用方法,大家可以参考下。 代码如下: String.prototype.Trim = function() { return this.replace(/^\s+/g,””).replace(/\s+$/g,””); } function JSCookie() {...
1.兼容firefox的 outerHTML,FF中没有outerHtml的方法。 代码如下: if (window.HTMLElement) { HTMLElement.prototype.__defineSetter__(“outerHTML”,function(sHTML) { var r=this.ownerDocument.createRange(); ...
1.3 小结..............................................8 第 2 章 ECMAScript 基础...............................................9 2.1 语法..............................................9 2.2 变量...........