关于 this 的指向问题,为什么这里的 this 指向 window?

2017-12-13 16:16:34 +08:00
 rabbbit
function person() {
    this.name = 'anna';
    this.printThis = function(){
        console.log(this) // Window 
    };
    this.handle = function(method){
        method();
    };   
} 
var p = new person();
p.handle(p.printThis);

console.log(this)中的 this 不是应该指向 p 吗?

2136 次点击
所在节点    JavaScript
8 条回复
GaryMa
2017-12-13 16:31:35 +08:00
你这里是 p.printThis,不是 p.printThis(), 相当于在外面有个变量 var fun = p.printThis, 然后将 fun 当做参数传给了 p.handle(), 实际上这个 fun 挂在的对象是最外面的作用域,也就是这里的 window
cont
2017-12-13 16:44:14 +08:00
关键字:this,上下文
```
我知道的是:this 一般有几种调用场景
var obj = {a: 1, b: function(){console.log(this);}}
1、作为对象调用时,指向该对象 obj.b(); // 指向 obj
2、作为函数调用, var b = obj.b; b(); // 指向全局 window
3、作为构造函数调用 var b = new Fun(); // this 指向当前实例对象
4、作为 call 与 apply 调用 obj.b.apply(object, []); // this 指向当前的 object
```
sensui7
2017-12-13 16:50:36 +08:00
因为你把 p.printThis 赋值给了 handle 的参数 method,你直接调用的 method, 已经没有 receiver 了,就是 window 了,
箭头函数的 this 是基于词法的, 不管怎么调用的, 它的 this 永远是定义时的 this。
shiny
2017-12-13 17:06:03 +08:00
lz 需要一本 《 JavaScript 权威指南》补补身体(手动狗头)
Tonni
2017-12-13 17:16:26 +08:00
this 取决于 call-site,想要解决这个问题可以这么弄:

```
p.handle(p.printThis.bind(p));
```

或者用 ES6 的 Arrow function:

```js
function person() {
this.name = 'anna';
this.printThis = () => {
console.log(this) // Window
};

this.handle = function(method){
method();
};
}
var p = new person();
p.handle(p.printThis);
```

楼主可以看看这个系列的介绍 https://github.com/getify/You-Dont-Know-JS/blob/master/this%20%26%20object%20prototypes/ch1.md
TabGre
2017-12-13 21:00:12 +08:00
console 是 window.console 调用
enginex
2017-12-14 13:01:11 +08:00
前端小白,我的理解是 JS 中 this 默认是动态作用域,看运行时上下文,p.handle(p.printThis)中的 p.printThis,实质是作为参数,被外围一个函数调用,属于函数直接调用,而非作为对象的方法调用,故指向 window。如果改成下面这样就 OK:
```js
function person() {
this.name = 'anna';
this.printThis = () => {
console.log(this) // p
};
this.handle = function(method){
method();
};
}
var p = new person();
p.handle(p.printThis);
```
因为箭头函数中 this 是静态作用域,主要看定义时上下文,即外层函数的 this (这里是 p ),所以调用后依旧指向 p
airhunter
2017-12-14 18:10:14 +08:00
我的理解是,你的匿名函数实际等同于在对象外面。类似如下:
function consolewin(){
console.log(this) // Window
};

function person() {
this.name = 'anna';
this.printThis = consolewin
this.handle = function(method){
method();
};
}
var p = new person();
p.handle(p.printThis);

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/414430

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX