如果函数的词法环境是在函数*定义*时创建的,那么为什么在*函数之后可以声明一个自由变量?(if a function's lexical environment is created at

编程入门 行业动态 更新时间:2024-10-23 19:21:24
如果函数的词法环境是在函数*定义*时创建的,那么为什么在*函数之后可以声明一个自由变量?(if a function's lexical environment is created at the time the function is *defined*, then why can a free variable be declared *after* the function?)

编辑:谢谢你的答案,我想我现在明白了。 它需要了解范围和吊装。 下面是一个我认为很好地说明的新例子:

var a = function (){ alert(x); } var x = 1; (function(){ var x = 2; a(); })();

上面的警报1.词典范围通过这个警报1而不是2来说明,并且通过“var x = 1”行在声明和定义匿名函数之后出现这一事实来说明提升。 “警报(X)”。 据称,吊装意味着上述内容相当于以下内容(来源: http : //www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html ):

var x; var a = function (){ alert(x); } x = 1; (function(){ var x = 2; a(); })();

因此,由于x在函数定义之前被有效初始化,因此“alert(x)”中的x与随后设置为1的x相同。

由于JS使用词法范围,因此“var x = 2”行不会覆盖与a关联的x

那是对的吗?

---原始问题---

我花了很多时间试图解决这个问题。 我在Javascript中阅读了一些关于范围和闭包的文章,但这仍然让我无法理解。

我被告知函数的词法环境是在定义函数时创建的,而不是在执行函数时创建的。

因此,如果在我的程序中没有任何名为x的变量声明,那么当我这样做时,指向匿名函数的闭包环境是什么?:

var a = func(){ var y = 7; //just for illustrative purposes alert(x); });

我的理解是环境是变量名称到值的映射......所以它会是

y: 7 x: ?

那是对的吗? 以下代码提醒“10”:

(function (){ var a = function(){ alert(x); }; var x = 10; a(); })();

我的猜测是,当调用a时,JS检查闭包环境是否有x的映射并且找不到,然后检查本地环境并通过“var x = 10”找到x设置为10。 是对的吗?

如果是这种情况,那么我希望以下内容也可以,但它不会:

var a = function(){ alert(x); }; (function (){ var x = 10; a(); })();

我期望发生的是,当执行a时,“alert(x);” 运行时,它检查x的闭包环境,找不到,然后检查“var x = 10”所在的外部环境并找到x。 但相反,我得到一个错误,即没有定义x

也许如果我能够知道在设置为a的匿名函数最初定义时 - 即当解释器在“alert(x)”中遇到x时,解释器完成了什么“准备”工作会有所帮助。

谢谢

EDIT: thanks for the answers, I think I get it now. It requires an understanding of scope and hoisting. Below is a new example that I think illustrates both well:

var a = function (){ alert(x); } var x = 1; (function(){ var x = 2; a(); })();

The above alerts 1. Lexical scope is illustrated by the fact that this alerts 1 and not 2, and hoisting is illustrated by the fact that the "var x = 1" line comes after the declaration of a and definition of the anonymous function with the "alert(x)". Allegedly, hoisting means that the above is equivalent to the below (source: http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html):

var x; var a = function (){ alert(x); } x = 1; (function(){ var x = 2; a(); })();

So since x is effectively initialized before the function definition, the x in "alert(x)" is the same x that subsequently gets set to 1.

Since JS uses lexical scope, the line "var x = 2" does not override the x associated with a.

Is that about right?

---original question---

I've spent pretty much all day trying to figure this out. I've read a few articles on scope and closures in Javascript, but this still eludes me.

I'm told that a function's lexical environment is created when the function is defined, not when it is executed.

So if there is no variable called x declared anywhere in my program, then what is the closure environment for the anonymous function that a points to when I do this?:

var a = func(){ var y = 7; //just for illustrative purposes alert(x); });

My understanding is that an environment is a mapping of variable names to values...so it would be

y: 7 x: ?

Is that correct? The following code alerts "10":

(function (){ var a = function(){ alert(x); }; var x = 10; a(); })();

My guess would be that when a is called, the JS checks the closure environment for a mapping for x and finds none, and subsequently checks the local environment and finds the x set to 10 by "var x = 10". Is that right?

If that were the case, then I would expect the following would also work, and yet it does not:

var a = function(){ alert(x); }; (function (){ var x = 10; a(); })();

What I would expect to happen is that, when a is executed, and "alert(x);" is run, it checks the closure environment for x, finds none, then checks the outer environment where "var x = 10" is and finds that x. But instead I get an error that x isn't defined.

Maybe it would help if I could know what 'preparatory' work is done by the interpreter when the anonymous function that a is set to is initially defined--i.e. when the interpreter encounters the x in "alert(x)".

Thanks

最满意答案

将闭包视为堆栈。 每个函数在该堆栈中都有一个map / hash。 这是一个示例,其中每个级别的值都由子闭包覆盖。

function a(){ var x = 2; function b(){ var x = 3; function c(){ var x = 4; } } }

当引用x的值时,js处理器在当前闭包中查找。 找到未定义的,它走向封闭堆栈试图找到一个值。 只有当达到顶级或“全局”范围时,它才会放弃并给出“未定义”的值。

你的例子在这里:

var a = function(){ alert(x); //no value of x in this closure }; //no value of x in this closure either (function (){ var x = 10; //this is a completely separate stack a(); //no value of 'a' in this closure, but there is one in global scope })();

我可以看到'a'函数的混淆,不知道匿名函数中的'x'。 闭包范围被定义为“写入”而不是“被称为”。 您不能从闭包范围之外的函数闭包范围中注入或混淆变量。 关于js的事情之一让我疯狂,我希望与众不同。 我很想拥有一套用于搞乱封闭范围的关键词......

Think of closure as a stack. Each function has a map/hash in that stack. Here's an example where each level has a value of x that is overwritten by a sub-closure.

function a(){ var x = 2; function b(){ var x = 3; function c(){ var x = 4; } } }

When referencing a value of x, the js processor looks in the current closure. Finding undefined, it walks up the closure stack attempting to find a value. Only when reaching the top level or 'global' scope does it give up and give the value of 'undefined'.

Your example here:

var a = function(){ alert(x); //no value of x in this closure }; //no value of x in this closure either (function (){ var x = 10; //this is a completely separate stack a(); //no value of 'a' in this closure, but there is one in global scope })();

I can see the confusion on the 'a' function not knowing about the 'x' in the anonymous function. Closure scopes are defined 'as written' not 'as called'. You can't inject or mess with variables in a functions closure scope from outside that closure scope. It is one of the things about js that drives me crazy and that I wish were different. I'd so love to have a set of keywords for messing with closure scope...

更多推荐

本文发布于:2023-07-28 19:04:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1308173.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:函数   词法   是在   变量   定义

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!