javascript this指向问题

var name = 'tom';
function fn() {
     this.name = 'jerry';
     
     setTimeout(function () {
         console.info(this == window);
         console.info(this.name);
     }, 1000);   
}
window.fn();
var f = new fn();

我的理解:setTimeout中匿名函数this指向window,但是console.info(this.name)输出jerry。不太理解。
如果我换一种方式调用fn即var f = new fn();console.info(this.name)输出tom。以上。多谢。

阅读 4.1k
9 个回答

var name = 'tom';
function fn() {

 //语句1
 this.name = 'jerry';//这里的this谁调用就指向谁
     setTimeout(function () {
     console.info(this == window);//这里的this始终指向window
 //语句2
     console.info(this.name);
 }, 1000);   

}
window.fn();//这里是window调用的,语句1把window的name赋值成了jerry,所以语句2打印jerry

我回答过类似的this问题,这里就不说了,请戳这里

执行window.fn();

this.name = 'jerry';

这里的this已经指向window了 你手动吧window的name设置成 jerry 下面当然返回jerry、

当fn作为构造函数执行的时候 this指向的是将来创建的实例,并没有影响window.name属性

延迟函数的执行函数的 this 始终指向的是全局,浏览器端是 window。window.fn()执行时,fn()中的 this 指向的是 window,this.name = 'jerry'修改了全局的 name 的值,所以打印出的是「jerry」。而var f = new fn()执行时,this 指向的是 fn,所以没有改变全局 name 的值,所以打印的是 「tom」。

在你执行fn()函数的时候,fn作用域内的this也是指向window的,仔细看看你的代码:

function fn() {
     this.name = 'jerry';
     
     setTimeout(function () {
         console.info(this == window);
         console.info(this.name);
     }, 1000);   
}
fn();

运行fn,this.name = 'jerry',这里全局变量的name就已经被修改成了jerry,1000ms之后执行的匿名函数获取全局变量的name就已经是jerry了。

更多可以查看我近期发表的文章JavaScript中this关键字

var name = 'tom';
function fn() {
     console.log(this.name);  // 'tom'  this指向window
     this.name = 'jerry';    // 改变了this.name的值
     console.log(this.name);  // 'jerry' this指向window
  
     setTimeout(function () {
         console.log(this.name);  // 'jerry' 同上,this指向window
         console.info(this == window);
         console.info(this.name);  // 'jerry' this指向window
     }, 1000);   
}
window.fn();


var f = new fn();  // new方法里面的this会指向创建的实例也就是f,不会去影响window.name this指向f
console.log(f.name);  // 'tom'

其实两个地方的this都是window
第一个地方是对象调用,this指向调用对象window

第二个地方是全局调用,this指向作用域链顶层

定时器里面的this始终指向作用域顶层window

所以答案很明显了

第一种(window.fn();):
fn此次调用的this隐式绑定到了window下执行,this.name也就是window.name = 'jerry',至此全局的name从'tom'变成了'jerry'。然后调用一个计时器函数,计时器内的匿名回调函数中的this默认绑定到window上,所以this == window为true,this.name也就是window.name为'jerry';
第二种(var f = new fn();):
fn此次调用的this为new绑定,绑定对象为new出来的fn实例(命名为f),this.name也就是f.name = 'jerry',然后调用一个计时器函数,计时器内的匿名回调函数中的this默认绑定到window上,所以this == window为true,this.name也就是window.name为'tom';

1、setTimeout里面的this指向window,这个就不要说了吧

2、我们重点关注下console.info(this.name);打印的内容,让我们运行一段代码看看

var name = 'tom';
function fn() {
     this.name = 'jerry';
}
window.fn();
console.log(name);

什么?上面竟然输出了jerry...

对的,你没有看错,执行window.fn();时候,代码里面的this指向window,所以相当于是widow.name = 'jerry';

所以执行你的代码,输出也就不奇怪了吧!

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏