What is lexical scope?

2018-12-31 04:21发布

Could someone please give me a brief introduction to lexical scoping?

13条回答
不再属于我。
2楼-- · 2018-12-31 04:50

IBM defines it as:

The portion of a program or segment unit in which a declaration applies. An identifier declared in a routine is known within that routine and within all nested routines. If a nested routine declares an item with the same name, the outer item is not available in the nested routine.

Example 1:

function x() {
    /*
    Variable 'a' is only available to function 'x' and function 'y'.
    In other words the area defined by 'x' is the lexical scope of
    variable 'a'
    */
    var a = "I am a";

    function y() {
        console.log( a )
    }
    y();

}
// outputs 'I am a'
x();

Example 2:

function x() {

    var a = "I am a";

    function y() {
         /*
         If a nested routine declares an item with the same name,
         the outer item is not available in the nested routine.
         */
        var a = 'I am inner a';
        console.log( a )
    }
    y();

}
// outputs 'I am inner a'
x();
查看更多
浪荡孟婆
3楼-- · 2018-12-31 04:53
var scope = "I am global";
function whatismyscope(){
   var scope = "I am just a local";
   function func() {return scope;}
   return func;
}

whatismyscope()()

The above code will return "I am just a local". It will not return "I am a global". Because the function func() counts where is was originally defined which is under the scope of function whatismyscope.

It will not bother from whatever it is being called(the global scope/from within another function even), that's why global scope value I am global will not be printed.

This is called lexical scoping where "functions are executed using the scope chain that was in effect when they were defined" - according to JavaScript Definition Guide.

Lexical scope is a very very powerful concept.

Hope this helps..:)

查看更多
与君花间醉酒
4楼-- · 2018-12-31 04:53

Lexical (AKA static) scoping refers to determining a variable's scope based solely on its position within the textual corpus of code. A variable always refers to its top-level environment. It's good to understand it in relation to dynamic scope.

查看更多
笑指拈花
5楼-- · 2018-12-31 04:54

Scope defines the area, where functions, variables and such are available. The availability of a variable for example is defined within its the context, let's say the function, file, or object, they are defined in. We usually call these local variables.

The lexical part means that you can derive the scope from reading the source code.

Lexical scope is also known as static scope.

Dynamic scope defines global variables that can be called or referenced from anywhere after being defined. Sometimes they are called global variables, even though global variables in most programmin languages are of lexical scope. This means, it can be derived from reading the code that the variable is available in this context. Maybe one has to follow a uses or includes clause to find the instatiation or definition, but the code/compiler knows about the variable in this place.

In dynamic scoping, by contrast, you search in the local function first, then you search in the function that called the local function, then you search in the function that called that function, and so on, up the call stack. "Dynamic" refers to change, in that the call stack can be different every time a given function is called, and so the function might hit different variables depending on where it is called from. (see here)

To see an interesting example for dynamic scope see here.

For further details see here and here.

Some examples in Delphi/Object Pascal

Delphi has lexical scope.

unit Main;
uses aUnit;  // makes available all variables in interface section of aUnit

interface

  var aGlobal: string; // global in the scope of all units that use Main;
  type 
    TmyClass = class
      strict private aPrivateVar: Integer; // only known by objects of this class type
                                    // lexical: within class definition, 
                                    // reserved word private   
      public aPublicVar: double;    // known to everyboday that has access to a 
                                    // object of this class type
    end;

implementation

  var aLocalGlobal: string; // known to all functions following 
                            // the definition in this unit    

end.

The closest Delphi gets to dynamic scope is the RegisterClass()/GetClass() function pair. For its use see here.

Let's say that the time RegisterClass([TmyClass]) is called to register a certain class cannot be predicted by reading the code (it gets called in a button click method called by the user), code calling GetClass('TmyClass') will get a result or not. The call to RegisterClass() does not have to be in the lexical scope of the unit using GetClass();

Another possibility for dynamic scope are anonymous methods (closures) in Delphi 2009, as they know the variables of their calling function. It does not follow the calling path from there recursively and therefore is not fully dynamic.

查看更多
冷夜・残月
6楼-- · 2018-12-31 04:54

Lexical scoping: Variables declared outside of a function are global variables and are visible everywhere in a JavaScript program. Variables declared inside a function have function scope and are visible only to code that appears inside that function.

查看更多
还给你的自由
7楼-- · 2018-12-31 04:58

I love the fully featured, language-agnostic answers from folks like @Arak. Since this question was tagged JavaScript though, I'd like to chip in some notes very specific to this language.

In javascript our choices for scoping are:

  • as-is (no scope adjustment)
  • lexical var _this = this; function callback(){ console.log(_this); }
  • bound callback.bind(this)

It's worth noting, I think, that JavaScript doesn't really have dynamic scoping. .bind adjusts the this keyword, and that's close, but not technically the same.

Here is an example demonstrating both approaches. You do this every time you make a decision about how to scope callbacks so this applies to promises, event handlers, and more.

Lexical

Here is what you might term Lexical Scoping of callbacks in JavaScript:

var downloadManager = {
  initialize: function() {
    var _this = this; // Set up `_this` for lexical access
    $('.downloadLink').on('click', function () {
      _this.startDownload();
    });
  },
  startDownload: function(){
    this.thinking = true;
    // request the file from the server and bind more callbacks for when it returns success or failure
  }
  //...
};

Bound

Another way to scope is to use Function.prototype.bind:

var downloadManager = {
  initialize: function() {
    $('.downloadLink').on('click', function () {
      this.startDownload();
    }.bind(this)); // create a function object bound to `this`
  }
//...

These methods are, as far as I know, behaviorally equivalent.

查看更多
登录 后发表回答