关于 javascript:对象字面量中的作用域

Scope in object literal

为什么在示例一中没有定义,而在示例二中定义了?
我认为箭头符号将允许绑定在更高的范围内,在这种情况下是对象文字。

示例 1:

1
2
3
4
5
6
7
8
9
10
11
12
var runApp = {
    init: () => {
         console.log(this); //this is an empty object.  
         this.run() //will crash here, run not a function of this.
    },
    run: () => {
         console.log("It's running!");
    }
};

// Now we call init
runApp.init();

示例 2:

1
2
3
4
5
6
7
8
9
10
11
12
var runApp = {
    init: function(){
         console.log(this);  
         this.run()
    },
    run: function() {
         console.log("It's running!");
    }
};

// Now we call init
runApp.init();


在第一个示例中,this 不是指名为 runApp 的对象,而是执行 runApp.init() 的上下文,因此称为"执行上下文"。例如:

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

var runApp = {
    init: () => {
         runApp.run() // This will work

         this.run() // This will not work

         console.log(this.orange); // Prints orange
    },
    run: () => {
        console.log("I am running!");
    }
};

// Now we call init
runApp.init();

你会注意到在上面的代码中 this.orange 是定义的,而 this.run() 是未定义的。注意:这适用于浏览器,但不适用于 Node.js。

您可以在此处阅读更多相关信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#No_separate_this


不,箭头函数不会增加更高的范围。只有常规函数可以。箭头函数很特别,因为它们在它之前引入了作用域。获取定义函数的范围。

这在某些地方很有用,比如构造函数。您不必将变量定义为 this 以在函数中使用。但在其他情况下,当您需要获取新范围时,您需要使用常规函数。这就是为什么你不能用箭头函数创建构造函数。

这里是箭头函数 (MDN) 的文档。


这是因为您使用的是箭头函数。箭头函数将始终保持其语法定义的上下文。在您的示例中,这很可能是未定义 init 函数的窗口或全局对象。

非箭头函数将根据它们被引用的对象动态确定上下文。除非上下文已在之前通过 .bind 明确设置,或者在调用站点通过 .apply.call 明确设置。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#No_separate_this


箭头函数从创建它们的上下文中继承这一点。

常规函数上下文是根据在点符号之前调用它们的对象动态确定的。例如 myObj.init() 所以 init 的上下文将是 myObj 并且这将被引用到 myObj。除非上下文已在调用站点显式设置 .bind、.apply 或 .call 以更改调用上下文。

然而,上面的胖箭头方法可以用常规函数package来解决:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var orange ="orange";
var runApp = {
    a : 'object???',
    init : function() {
        return (() => {
            console.log(this.a)
        })();
    },
    run: () => {
        console.log("I am running!");
    }
};


// Now we call init
runApp.init();