在 JavaScript 中,this 是动态绑定,或称为运行期绑定的。一般而言,在Javascript中,this 指向函数执行时的当前对象。

由于其运行期绑定的特性,JavaScript 中的 this 可以是全局对象、当前对象或者任意对象,这完全取决于函数的调用方式。JavaScript 中函数的调用有以下几种方式:没有明确的调用对象,作为对象方法调用,使用 new 关键字作为构造函数调用,和使用 apply、 call 和 eval 调用。

没有明确的当前对象时

当没有明确的执行时的当前对象时,this 指向全局对象 window

纯粹的函数调用

举个栗子

1
2
3
4
5
6
var x = 1;
function test(){
var x = 2;
alert(this.x);
}
test(); // 1

再看个复杂的栗子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var name = "window";

var Bob = {
name: "Bob",
showName: function(){
alert(this.name);
}
}; var Tom = {
name: "Tom",
showName: function(){
var fun = Bob.showName;
fun();
}
}; Tom.showName();  //window

其实也不复杂,只要按照上面那句话来判断就行。

setTimeout、setInterval和匿名函数

在浏览器中 setTimeoutsetInterval 和匿名函数执行时的当前对象是全局对象 window,这条可以看成是上一条的一个特殊情况。

1
2
3
4
5
6
7
8
9
10
11
12
var name = "Bob";  
var nameObj = {
name : "Tom",
showName : function(){
alert(this.name);
},
waitShowName : function(){
setTimeout(this.showName, 1000);
}
}; nameObj.waitShowName(); // Bob

setTimeout 可以看做是一个延迟执行的匿名函数。

1
2
3
4
5
waitShowName : function(){  
function(__callback){
__callback();
}(this.showName);
}

由于匿名函数的当前对象是 window,所以当在该匿名函数中运行回调函数时,回调函数的 this指向了 window,所以 alert 出来 window.name 。

作为对象方法调用时

使用这种调用方式时,this 被自然绑定到该对象。

通常情况

1
2
3
4
5
6
7
8
var text = 'window'
var obj = {
text: 'obj',
foo: function(){
console.log(this.text);
}
}
obj.foo(); // obj

内部函数调用

但是,如果在 obj 的 foo() 内部再声明一个函数,在内部函数中调用 this,像下面这样:

1
2
3
4
5
6
7
8
9
10
11
12
'use strict';
var obj = {
text: 'hello world',
foo: function(){
return function(){
console.log(this.text);
}()
}
} obj.foo();
// Uncaught TypeError: Cannot read property 'text' of undefined

这是因为 this 指针只在 foo 方法的函数内指向 obj ,在函数内部定义的函数, this 又指向undefined 了!(在非 strict 模式下,它重新指向全局对象 window !)

修复的办法是用一个 that 变量首先捕获 this :

1
2
3
4
5
6
7
8
9
10
11
'use strict';
var obj = {
text: 'obj',
foo: function(){
var that = this;
return function(){
console.log(that.text);
}()
}
}
obj.foo(); // obj

三种特殊情况

new关键字 - 作为构造函数调用时

所谓构造函数,就是通过这个函数生成一个新对象。这时,this 就指这个新对象。

1
2
3
4
5
6
7
8
9
10
function Person(__name){
this.name = __name;
// this 指向使用该构造函数构造的新对象
}
Person.prototype.show = function(){
alert(this.name);
} var Bob = new Person("Bob");
Bob.show(); //Bob

apply 和 call

在 JavaScript 中函数也是对象,对象则有方法,apply() 和 call() 就是函数对象的方法。它们能够强制改变函数执行时的当前对象,让 this 指向其他对象。

apply() 接收两个参数,第一个参数就是需要绑定的this变量,第二个参数是 Array,表示函数本身的参数。call() 与 apply() 的唯一区别就是把函数本身的参数一个个传入。

1
2
3
// 对普通函数调用,通常把 this 绑定为 null
Math.max.apply(null, [3, 5, 4]); // 5
Math.max.call(null, 3, 5, 4); // 5

举个使用 apply() 改变当前对象的栗子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var name = "window";

var someone = {
name: "Bob",
showName: function(){
alert(this.name);
}
}; var other = {
name: "Tom"
}; someone.showName.apply(); // window
someone.showName.apply(other); // Tom

apply() 的参数为空时,默认调用全局对象。

eval

对于 eval 函数,其执行时候似乎没有指定当前对象,但实际上其 this 并非指向 window,因为该函数执行时的作用域是当前作用域,即等同于在该行将里面的代码填进去。

1
2
3
4
5
6
7
8
9
10
var name = "window";

var Bob = {
name: "Bob",
showName: function(){
eval("alert(this.name)");
}
}; Bob.showName(); //Bob

参考

  1. 对 js 中 this、apply、call 和闭包的理解
  2. Javascript中this关键字详解
  3. 深入浅出 JavaScript 中的 this
  4. Javascript的this用法

JavaScript 中 this 的用法的更多相关文章

  1. JavaScript中return的用法详解

    JavaScript中return的用法详解 最近,跟身边学前端的朋友了解,有很多人对函数中的this的用法和指向问题比较模糊,这里写一篇博客跟大家一起探讨一下this的用法和指向性问题. 1定义 t ...

  2. JavaScript中this的用法 及 如何改变this的指向

    要懂得JavaScript中this的用法,首先需要知道,JavaScript中的作用域相关知识. var fun = function(){ var flag = 1; console.log(fl ...

  3. javascript中 try catch用法

    javascript中 try catch用法 投稿:hebedich 字体:[增加 减小] 类型:转载 时间:2015-08-16我要评论 JS try catch语句一般在什么情况下使用?是必须使 ...

  4. 从函数调用的角度,探讨JavaScript中this的用法

    js函数调用方式大概可分为:函数调用,构造器调用,call或apply,方法调用四种方式.下面结合一些基础概念和实测代码,从函数调用的角度,探讨JavaScript中this的用法. 1. new对函 ...

  5. JavaScript中this的用法详解

    JavaScript中this的用法详解 最近,跟身边学前端的朋友了解,有很多人对函数中的this的用法和指向问题比较模糊,这里写一篇博客跟大家一起探讨一下this的用法和指向性问题. 1定义 thi ...

  6. 在HTML页面中实时获取新消息的方法 “JavaScript中的setInterval用法”

    JavaScript中的setInterval用法(资料来源:博主---八神吻你   ) setInterval动作的作用是在播放动画的时,每隔一定时间就调用函数,方法或对象.可以使用本动作更新来自数 ...

  7. JavaScript中一些怪异用法的理解

    引言 JavaScript这门语言有些场合的用法还是比较怪异的.这篇文章会尽量将这门语言特有的一些比较特殊的用法收集在一起.就当是平时开发时需要注意的地方吧. 特殊用法收集 1.!!用法 在JavaS ...

  8. JavaScript中Cookie的用法

    Javascript中Cookie主要存储于客户端的计算机中,用于存放已访问的站点信息,Cookie最大约为4k.以下实例主要用于页面在刷新时保存数据,具体的用法如下所示: <html> ...

  9. javaScript中with的用法

    1 JavaScript中的with语句的作用是为逐级的对象访问提供命名空间式的速写方式, 也就是在指定的代码区域, 直接通过节点名称调用对象 初次接触到with用法,是这样一段代码: 1 2 3 4 ...

  10. javascript中的继承用法

    本文实例汇总了javascript关于继承的用法,希望本文所述对大家的javascript程序设计有所帮助.分享给大家供大家参考.具体如下:代码如下: /** * 实现子类继承父类,但不会产生多余的属 ...

随机推荐

  1. Socket INADDR_ANY详解

    转载:http://hi.baidu.com/zorro_knight/item/37af9e8c9dc71253e73d1924 linux下的socket INADDR_ANY表示的是一个服务器上 ...

  2. Android开发project师,前行路上的14项技能

    导读: 你是否曾渴望回到宋朝? 或者什么朝,反正就是男耕女织的古代. 哦,那时的首都在汴梁(开封),房价想必没有如今这么高,工作?无非就是给你把锄头,去,种地去.夕阳西下了,麦子垛后,你和翠姑搂抱在一 ...

  3. C#调用API向外部程序发送数据

    C#调用API向外部程序发送数据 最近有可能要做一个项目.在项目中有这么一个功能,在A程序中调用B程序,同时在A程序中进行登陆后,要将A程序的登录名和密码自动填充到B程序的登陆对话框中,这样B程序就不 ...

  4. java生成自己定义的表ID

    需生成例如以下ID: 56d7ade1-87d1-4f54-8dc8-13611c8c2545 27181ad4-4214-4e12-af3a-911a0103a12f 24cafdfb-eac3-4 ...

  5. easyui datagrid如何获取到每行的文本框

    在return '<input type="text" name="txtCount" class="inputvalue"/> ...

  6. http://jingyan.baidu.com/article/7f41ecec1b7a2e593d095ce6.html

    http://jingyan.baidu.com/article/7f41ecec1b7a2e593d095ce6.html http://www.linuxeden.com/html/softuse ...

  7. SQL Server 表,记录 死锁解决办法

    我自己的数据库表记录死锁后的 根据以下资料的 解决方案: 1. 先根据以下语句 查询 哪些表被 死锁,及 死锁的  spid SELECT request_session_id spid,OBJECT ...

  8. 一招搞定多Offer选择

    12月9号在论坛看到一位毕业生问了一个问题: 如今两个offer 一个在南京,搞.net ,公司是国电南自.税前一年加起来几乎相同7.2万.一个是在上海.搞java,公司名叫鑫合汇(不知道各位有没实用 ...

  9. 吐槽win7

    在纠结了N次后,终于重装win7了.其间还是不死心,又找了新的xp版本来装了一下,确实不行,才心不甘情不愿地再次回到win7下. 说实话,Win7的各种新功能,我没有感觉到有多好,只有不适应,如: 资 ...

  10. shared memory segment exceeded your kernel's SHMMAX parameter

    http://wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server IpcMemoryCreate: shmget(key=5432001, s ...