V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
rabbbit
V2EX  ›  JavaScript

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

  •  
  •   rabbbit · 2017-12-13 16:16:34 +08:00 · 2284 次点击
    这是一个创建于 2566 天前的主题,其中的信息可能已经有所发展或是发生改变。
    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 吗?

    第 1 条附言  ·  2017-12-13 20:41:25 +08:00

    想了想,还是不太明白.
    为什么把this.getname赋值给变量c之后, c的this会发生变化呢.
    是因为this.getname是一个类的方法,而c是一个函数吗?

    function Cat() {
        this.name = 'anna';
        this.getname = function(){
            return this; //Window 
        }
        var c = this.getname;
        console.log(c());
    }
    new Cat();
    
    第 2 条附言  ·  2017-12-13 21:08:55 +08:00

    this指向调用者,例如下面的return this指向dog. 也许是 c = this.getname时上下文环境发生改变了吧.

    function Dog() {
        this.name = 'alice';
        this.getname = function(){
            return this;
        }   
    }
    var d =new Dog()
    
    function Cat() {
        this.name = 'anna';
        this.getname = function(){
            return this; // Dog {name: "alice", getname: ƒ}
        }
        d.getname = this.getname;
        console.log(d.getname());
    }
    new Cat();
    
    GaryMa
        1
    GaryMa  
       2017-12-13 16:31:35 +08:00   ❤️ 1
    你这里是 p.printThis,不是 p.printThis(), 相当于在外面有个变量 var fun = p.printThis, 然后将 fun 当做参数传给了 p.handle(), 实际上这个 fun 挂在的对象是最外面的作用域,也就是这里的 window
    cont
        2
    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
        3
    sensui7  
       2017-12-13 16:50:36 +08:00   ❤️ 1
    因为你把 p.printThis 赋值给了 handle 的参数 method,你直接调用的 method, 已经没有 receiver 了,就是 window 了,
    箭头函数的 this 是基于词法的, 不管怎么调用的, 它的 this 永远是定义时的 this。
    shiny
        4
    shiny  
       2017-12-13 17:06:03 +08:00
    lz 需要一本 《 JavaScript 权威指南》补补身体(手动狗头)
    Tonni
        5
    Tonni  
       2017-12-13 17:16:26 +08:00   ❤️ 1
    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
        6
    TabGre  
       2017-12-13 21:00:12 +08:00 via iPhone
    console 是 window.console 调用
    enginex
        7
    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
        8
    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);
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   840 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 68ms · UTC 21:04 · PVG 05:04 · LAX 13:04 · JFK 16:04
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.