JavaScript 里的 this 到底指得是什么?很多人都会告诉你 this 指的是当前对象。这样理解对么?在大多数情况下确实没错。比如我们经常会在网页上写这样的 JavaScript:
<
input
type
="submit"
value
="提交"
onclick
="this.value='正在提交数据'"
/>
这里的this显然指的是当前对象,即这个提交按钮。通常,我们使用this的情况都与此类似。但是有什么情况不是这样的呢?
大家看看这个例子:
var
foo
=
function
()
{
console.log(
this
);
}
foo();
new
foo();
比较一下 foo() 和 new foo() 的运行结果,你会发现,前者 this 指向的并非 foo 本身,而是当前页面的window对象,而后者才真正的指向foo。这是为什么呢?
其实这牵涉到JavaScript的一条重要特性,就是所谓的“闭包
”。闭包这个概念说复杂也不复杂,但也不是简单到能用一两句话说清。偶会在以后的文章中深入探讨这个Javascript 最重要的特性。现在,我要告诉大家的是,因为闭包的存在,JavaScript中的作用域
变得相当重要。
所谓的作用域
,简单的说,就是创建一个函数时在什么环境下创建的。而this变量的值,如果没有指定的话
,就是函数当前的作用域。
在
前面的例子里,foo() 函数是在全局作用域(这里就是window对象),所以this的值是当前的window对象。而通过 new foo()
这样的形式,其实是创建了一个foo()的副本,并在这个副本上进行的操作,所以这里的this就是foo()的这个副本。
这样讲可能有点抽象,大家来看个实际的例子:
<
input type="
button"
id
="aButton"
value
="demo" onclick="" />
<
script
type
="text/javascript"
>
function
demo()
{
this
.value
=
Math.random();
}
</
script
>
如果直接调用demo() 函数,程序就会报错,因为demo函数是在window对象中定义的,所以demo的拥有者(作用域)是window,demo的this也是window。而window是没有value属性的,所以就报错了。
如果我们通过创建副本
的方式,将这个函数的副本
添加到一个HTML元素,那么他的所有者就成了这个元素,this也指代了这个元素:
document.getElementById(
"
aButton
"
).onclick
=
demo;
这样就将aButton的onlick属性设置为demo()的一个副本,this也指向了aButton。
你甚至可以为多个不同的HTML元素创建不同的函数副本。每个副本的拥有者都是相对应的HTML元素,各自的this也都指向他们的拥有者,不会造成混乱。
但是,如果你这样定义某个元素的onlick事件:
<
input
type
="button"
id
="aButton"
value
="demo"
onclick
="demo()" /
>
点击这个button之后,你会发现,程序又会报错了——this又指向了window!
其实,这种方法并没有为程序创建一个函数,而只是引用了这个函数。
具体看一下区别吧。
使用创建函数副本的方法:
得到的输出是:
function
demo()
{
this
.value
=
Math.random();
}
使用函数引用的方法:
<
input
type
="button"
id
="aButton"
value
="demo"
onclick
="demo()"
/>
<
script
type
="text/javascript"
>
var
button
=
document.getElementById(
"
aButton
"
);
function
demo()
{
this
.value
=
Math.random();
}
alert(button.onclick);
</
script
>
得到的输出是:
function onclick() {
demo();
}
这样就能看出区别了吧。函数引用的方式中,onclick事件只是直接调用demo()函数,而demo()函数的作用域仍旧是window对象,所以this仍然指向window。
这
样就又引出了一个问题:既然函数副本这么好用,为什么还需要函数引用的方法呢?答案是性能。每新建一个函数的副本,程序就会为这个函数副本分配一定的内
存。而实际应用中,大多数函数并不一定会被调用,于是这部分内存就被白白浪费了。而使用函数引用的方式,程序就只会给函数的本体分配内存,而引用只分配指
针,这样效率就高很多。程序员么,节约为主,恩
所以我们来看一个更好的解决方案:
这样,效率和需求就都能兼顾了。
最后再多讲一句:在前面的文章里,我特别强调了“如果没有指定this的话”。其实this是可以指定的
。Function对象有两个方法:call()和apply()。这两个方法都支持指定一个函数中的this。有兴趣的话您可以去查一下Javascript的手册,看看这两个函数都是干什么用的。而我们经常用的 new foo() 可以用以下这段伪代码来描述:
现在明白了,在本文开头的第一个例子里,new foo() 的 this 为什么是 foo 了吧
原文:博客园
- 棕熊
- http://www.cnblogs.com/ruxpinsp1/archive/2008/04/20/1162463.html
分享到:
相关推荐
Presentations-JavaScriptThis-源码.rar
This is the official JavaScript SDK for Analysys. JavaScript SDK目录说明: demo——API调用演示 SDK——SDK文件 src——SDK源码 vue-demo——VUE框架API调用演示 安装 npm install ans-javascript-sdk --save ...
JavaScriptthis绑定规则以及箭头函数相关知识,以便于讨论学习
JavaScript中this的指向还没搞明白?来这看看 你就懂啦~
计算机后端-Java-PHP视频教程javascript03-215 this是谁.wmv
this指触发事件的对象,接下来为大家分享下javascript中onclick(this)的用法,感兴趣的朋友可以参考下哈,希望对你有所帮助
Modern JavaScript Video Project.This is the Modern JavaScript Repository. Suitable for learning how to use JavaScript.
This book is about programming JavaScript for the real world, using the techniques and workflow suggested by Test-Driven Development. It is about gaining confidence in your code through test coverage,...
Javascript的this用法
An exercise to practice JavaScript and use testing to create a solution. In this exercise, you will be able to: use data structures to organize your application information, learn how to model real...
JavaScript程序设计
JavaScript Koans is an interactive learning environment that uses failing tests to introduce students to aspects of JavaScript in a logical sequence. The inspiration for this project comes from the ...
JavaScript程序设计javascript中this的指向问题共6页.pdf.zip
Updated to include the latest coverage of JavaScript, including howit fits into current Web browsers and applications as well as an exploration of its interaction with XML data in Ajax - This mammoth ...
Javascript 中 this指向
This Fifth Edition is completely revised and expanded to cover JavaScript as it is used in today's Web 2.0 applications. This book is both an example-driven programmer's guide and a keep-on-your-desk ...
此插件可让您使用对输入的javascript文件进行。 入门 开始使用您最喜欢的软件包管理器。 用纱安装 纱线添加-D包裹插件模糊处理 使用npm安装 npm install -D parcel-plugin-混淆 在生产模式下运行宗地以混淆代码 ...
how to exploit CSS transforms to create rich depth in animations, and how to fully leverage JavaScript animation libraries like Velocity.js to streamline animation programming. From animation ...
JavaScript程序设计
JavaScript 中的 this 关键字是一个非常重要的概念,它经常会使开发者感到困 惑。通常来说,this 的值是在函数被调用时确定的,其值取决于函数被调用的方 式。本文将介绍 JavaScript 中 this 的用法,从而帮助开发者...