JavaScript范围和执行上下文 [英] JavaScript Scope and Execution Context

查看:55
本文介绍了JavaScript范围和执行上下文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试了解JavaScript范围规则.我在教科书和文档中所读的内容令人困惑.

I am trying to understand JavaScript scope rules. What I have read in textbooks and the documentation is confusing.

在我看来,JavaScript是一种静态(或按词法)作用域的语言-尝试将变量名绑定到变量(定义)时,将使用代码的词法结构.

It seems to me that JavaScript is a statically (or lexically) scoped language - when trying to bind a variable name to a variable (definition), the lexical structure of the code is used.

执行上下文似乎类似于调用堆栈上的堆栈框架.每个执行上下文都有一个变量对象,在该对象上定义了所有(关联函数的)局部变量.这些可变对象链接在一起,以提供从堆栈顶部的可变对象到堆栈底部的可变对象(窗口对象)的作用域链".在将变量名称绑定到变量的过程中,从上至下搜索该范围链.这与C/C ++/Java之类的静态作用域语言非常相似.

An execution context seems to be similar to a stack frame on the call stack. Each execution context has a variable object upon which all the local variables (of the associated function) are defined. These variable objects are linked together to provide a 'scope chain' from the variable object at the top of the stack to the variable object at the bottom of the stack (the window object). This scope chain is searched from top to bottom in binding variable names to variables. This is very similar to statically scoped languages like C/C++/Java.

与C/C ++/Java似乎有一个重要的区别-可以访问在函数中定义的变量,该函数的堆栈帧不再位于调用堆栈中,如以下示例所示:

There seems to be one important difference with respect to C/C++/Java -- it is possible to access a variable defined in a function whose stack frame is no longer on the call stack, as shown in the example below:

var color = "red";
var printColor;

function changeColor() {
    var color = "green";

    printColor = function(msg) {
        alert(msg + color);
    }
    printColor("in changeColor context, color = ");  // "green"
}

changeColor();

// stack frame for "changeColor" no longer on stack
// but we can access the value of the variable color defined in that function

printColor("in global context, color = ");  // "green"

我说对了吗?还有其他我应该注意的问题吗?

Have I got this right? Are there other issues I should be aware of?

预先感谢

推荐答案

这确实是C/C ++与JavaScript之间的主要区别:JavaScript是一种引用计数的垃圾收集语言,这意味着对象可以当它们不再有任何引用时,将被引擎回收.分配给 printColor 的函数本身就不在堆栈中,因为它将使用C或C ++;它是动态分配的,然后分配给当前范围之外的变量.因此,当控制流从 changeColor ,匿名函数的引用计数仍为 1 因为外部的 printColor 引用了它,因此可以从外部使用范围.

This is indeed a major difference between C/C++ and JavaScript: JavaScript is a reference-counted, garbage-collected language, which means that objects can be reclaimed by the engine when they no longer have any references to them. The function you assign to printColor isn't on the stack, per se, as it would be in C or C++; it's allocated dynamically and then assigned to a variable outside your current scope. So, when control flow returns from changeColor, the anonymous function still has a reference count of 1 since the outer printColor refers to it, and thus it's usable from the outer scope.

因此,您的示例并没有太大的范围问题-很明显,您声明 changeColor 的功能范围的 printColor 外部.当您定义 changeColor ,它关闭升值 printColor 进入新功能范围,使其可访问.喜欢战斗说,如果您将 var 添加到的第二个内部定义中 printColor ,它将 阴影 第一个您声明的 printColor ,该函数外部将无法访问它阻止.

So, your example isn't so much of a scoping issue--it's clear that you declare printColor outside of the function scope of changeColor. When you define changeColor, it closes the upvalue printColor into the new function scope, making it accessible. Like Combat said, if you add a var to the second, inner definition of printColor, it'll shadow the first printColor you declared and it won't be accessible outside that function block.

关于其他需要注意的问题,是的,有很多问题,但是请参阅我的评论您的原始帖子以取得良好的开端.

As far as other issues to be aware of, yes, there are quite a few, but see my comment on your original post for a good start.

这篇关于JavaScript范围和执行上下文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆