【问题标题】:What is the scope of a variable defined within a function expression in strict mode?严格模式下函数表达式中定义的变量的范围是什么?
【发布时间】:2013-01-19 19:20:19
【问题描述】:

据我了解,定义变量时,它会通过this 附加到“最近”的本地范围。

如果本地没有设置范围,则最近的范围变为window

然而,在严格模式中,本地范围设置为未定义而不是windowas part of the ECMAscript 5 spec designed to limit misuse of the global scope.


使用immediately invoked function expression pattern 和严格模式创建 jQuery 插件

;( function( $, window ){
   "use strict";
   var myScope = this;
   var myVar = 1;

   var myFunction = function(){
     console.log( myScope, myVar );
   } 

   $.myFunc = myFunction;

})( jQuery, window );

本地范围(上下文)未创建(通过函数调用),因此设置为未定义。

如果本地作用域未定义且window.myVar未定义,那么变量myVar的作用域是什么,如何访问它?

【问题讨论】:

    标签: javascript scope function-expression


    【解决方案1】:

    this context variableScope 没有任何关系,就 ECMAscript 如何在下面实现 词法作用域而言。

    this 将始终引用 调用对象,该对象可以在运行时更改,而 scope / context 无法获取改变了。您在那里有两个函数调用,每个函数调用都有自己的 Execution Context 和自己的 Activation Object 分别 Lexical Environment Record,由存储任何本地数据的实现,例如形式参数、变量和函数声明


    您在这里真正想要实现的是创建一个 hash / namespace 对象,该对象用作保存数据的容器。因此,你不应该分配this,而只是创建你自己的Object

    var myScope = { };  // respectively Object.create( null );
    

    严格模式下,对于任何被调用的函数按原样,实现只会将this 设置为undefined。这意味着,this 的值取决于 如何 调用函数。在您的情况下,它是一个自动执行的函数,因此,它的 thisstrict 模式window (global) 在 中将始终是 undefined >非严格模式

    【讨论】:

    • 我在问 myVar 的对象上下文是什么。我猜因为他们只是决定不将其设置为窗口,所以答案是准确的,未定义的。我认为给变量赋值意味着我应该可以访问一些上下文,如果它不是thiswindow,那么它应该是一些东西。
    • @qdeninja:完全正确。它仍然取决于如何调用函数,但在您的情况下,this 值将始终包含 undefined 在严格模式下。
    • @qdeninja:没有“use strict”的相同代码也不会将变量分配给窗口,但底层上下文在两种情况之间不会改变。换句话说,没有严格,你仍然无法做到window.myVarmyScope.myVar
    • @JimDeville:他当然会!如果没有严格模式this 将只是对window 的引用(如果我没听错的话)。他将无法从“外部”访问变量myVar,但他当然可以通过该引用访问他写入全局对象的任何内容。
    • @jAndy: 但由于它是模块范围的,并且myVar 是用var 声明的,所以它不会在this 上暴露。 IOW,你仍然不能做myScope.myVarwindow.myVar
    【解决方案2】:

    myVar 的作用域是包含闭包。当我运行您的代码,然后运行 ​​$.myFunc() 时,输出为 undefined 1,因为 myVar 仍然存在于该闭包中。但是,无法从闭包外部访问myVar。这与用于在 JS 中实现私有变量的机制相同。

    @jAndy 说的也对,this 与作用域无关,在这种情况下匿名函数的thisundefined

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-17
      • 1970-01-01
      • 2014-11-07
      • 1970-01-01
      • 1970-01-01
      • 2014-07-24
      • 2015-10-11
      • 2013-07-31
      相关资源
      最近更新 更多