JS关于function中this的指向问题

<script>
    function fn1() {
        console.log(this);
    }
    fn1(); //第一次调用fn1:window

    class People {
        excutor(fn1) {
            function fn2() {
                console.log(this);
            }

            fn1(); // 第二次调用fn1:window
            console.log(this); // p 
            fn2(); // undefined
        }
    }

    let p = new People();
    p.excutor(fn1);
</script>

根据 “JS中函数的this为其调用者”

第一个问题:

fn1第一次被调用在window中,所以其输出为window,第二次将其作为参数传入p.excutor()中调用,为什么this还是window?

第二个问题:

fn2在Person中的excutor中定义,根据ES6语法,class中默认是严格模式,所以在p.excutor()中调用fn2其this是undefined。如果将fn2放在非class环境中调用为什么fn2的this还是undefined?

第三个问题:

综合以上现象,是否能说明 “JS中函数的this并不是其调用者的this,而是其被定义时所处环境的this”? 比如:fn1在window中定义所以fn1的this一直是window,fn2在class中定义所以fn2的this一直是undefined?

阅读 3.7k
5 个回答

第一个问题:“JS中函数的this为其调用者”,你传入哪里不重要,重要的谁调用的。fn1()看做 window.fn1()

第二个问题:“JS中函数的this为其调用者” 。严格模式是严格模式。但是和你说的环境无关。还是去找调用,代码中没有看到你如何构建环境。

第三个问题:“JS中函数的this为其调用者” 。你这里偷换了概念 JS中函数的this并不是其调用者的this , 一直说的都是调用者,你为什么要加 的this


fn1() 看做 window.fn1() 注意这里。

你的例子本身就没有体现出调用者,只体现出了定义者和执行环境

image.png

function fn1(){
    console.log(this,'fn1')
} 

class People {
        excutor2(fn){
            fn();
        }
        excutor(fn3) {
            function fn2() {
                console.log(this,'fn2');
            }
            fn2();

            this.excutor2(fn1)
            this.excutor2(fn2)
            
            this.excutor2(fn3)
            this.excutor2(function (){
                console.log(this,'fn4')
            })
        }
    }

    let p = new People();
    p.excutor(fn1);

我也尝试了一下, 我认为结论是函数前面没有.它的情况下 this指向定义它所处环境的this

阮一峰大佬说的是,this会指向该方法运行时所在的环境,我个人感觉和他定义的环境一个样子~

可以从 AST 的角度去理解
a.fun() 这块代码是调用表达式,调用者是 a.fun 是一个 MemberExpression
fun() 这块代码是调用表达式,调用者是 fun 是一个 Identifier
如果调用者是 MemberExpression,那么函数的 this 就是 MemberExpression 的 object,也就是 a
如果调用者是 Identifier,如果函数在被声明时的作用域是 严格模式,那么 this 是 undefined,反之是 window


先推荐个文章:JavaScript 的 this 指向问题深度解析 - SegmentFault 思否

题主这里遇到的问题实际有两个

  1. this 指向的问题 —— 这个好回答:如果不绑定 this 对象,this 指向成员调用者,也就是 obj.fn() 这里 . 前面这个对象。如果没有成员访问,那指向的情况见下条
  2. strict(严格)模式下,指向全局对象;strict 模式下是 undefined

题主是在 Web 环境跑的,非 type="module" 的代码,默认是非严格的,所以 fn1 的中的 this 总是指向 window。问题是,类似的 fn2 中,为什么 thisundefined 呢? —— 这是因为 fn2 是在在 class 中声明的,而 class 声明中一定是 strict 格式。type="module" 的时候,也是严格模式,可以试试下面的代码

<script type="module">
    (function() {
        console.log("this is ", this);
    })();
</script>
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题