问题标签 [lexical-scope]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
6 回答
3529 浏览

scheme - 使用 let/set “记住”值的方案函数

我是 Scheme 的新手,并试图了解函数中出现的某些值如何在多种用途中持续存在。采取以下柜台:

我无法弄清楚(并且在任何地方都没有找到解释),是为什么next每次使用时都不会重置为 0 count

0 投票
3 回答
334 浏览

perl - Perl 的词法范围的编译指示是如何实现的?

autodie根据文档,编译指示(如)是词法范围的。

这是否适用于所有加载的模块use?据我所知,use几乎与以下内容相同:

BEGIN发生在编译时,并且 require 没有词法范围。那么如何autodie知道它的范围呢?

0 投票
1 回答
515 浏览

emacs - emacs 词法作用域和带引号的变量名

我正在尝试 Emacs 词法作用域(Emacs 24 的新特性)之间add-to-list的相互作用,发现相互作用令人困惑,我不知道如何理解它。这是一个最小的示例,除了我使用set而不是add-to-list. (set类似于add-to-list它通常采用带引号的变量名)

上面的代码按顺序打印“mature apple”、“mature apple”、“by set”。第一个打印结果“成熟的苹果”与词法作用域的预期一致(支持词法闭包),在这里看到并不奇怪。但是第二次和第三次打印的结果让我感到惊讶。好像(set 'a "by set")只是识别和影响 name 的全局绑定a

这是预期的行为吗?或者这是一个错误?如果有意,如何理解这种行为?

我是否正确地假设set只要词法范围打开,它总是会影响全局绑定?

使用(eval '(progn ...) nil)时,事情会按照动态作用域的预期工作,并且 的行为与这种情况下的行为(set 'a ...)相同(setq a ...)。只有当一个人同时使用词法作用域和带引号的变量时,才会出现这个问题。


更新:

根据手册,这似乎是一种预期的行为。在Void Variables上,手册说

在词法绑定规则下,值单元只保存变量的全局值,即任何词法绑定结构之外的值。当一个变量被词法绑定时,局部值由词法环境决定;如果其符号的值单元格未分配,则该变量可能具有局部值。

词法绑定

symbol-value、boundp 和 set 等函数仅检索或修改变量的动态绑定(即其符号值单元格的内容)。

symbol-value、boundp、set 是通常用带引号的变量名 ( (symbol-value 'var) (boundp 'var) (set 'var 123)) 调用的函数。这些函数仅获取或设置符号的值单元格,并且在词法绑定规则下,值单元格仅保存全局值。所以在词法绑定下,使用带引号的变量只能获取或设置全局值(除非变量是特殊变量)。尽管结果既不是词汇(苹果)也不是动态(香蕉)看起来仍然很奇怪。

0 投票
3 回答
1092 浏览

emacs - Emacs:defun 或 defmacro 主体中的代码不能引用周围的词法变量?

2013 年 5 月更新:从 GNU Emacs 24.3.1 开始,(let .. (defun..)) bytecompiles 很好,没有警告,bytecompiled 代码与未编译代码一样工作。只是不要忘记将文件变量添加lexical-binding: t到要进行字节编译的文件中。现在不需要在此问题末尾的解决方法。


Lexical Binding - Emacs Lisp Manual有这一段:

请注意,symbol-value、boundp 和 set 等函数仅检索或修改变量的动态绑定(即其符号值单元格的内容)。此外,defun 或 defmacro 主体中的代码不能引用周围的词法变量。

我不确定我是否理解了第二句话的意思。在下面应该以词法绑定模式运行的代码中,defun 主体中的代码成功地引用了 name 的词法绑定值n

这句话只是说 (let .. (defun ..)) 是一种不好的做法吗?


解决方法

这是测试上述代码的代码:

0 投票
1 回答
212 浏览

r - `getClasses()` 中默认环境的模糊变化(标准函数与正式 S4 方法)

关于“环境嵌套”/词法范围,我很难弄清楚这里到底发生了什么:

问题

where函数中参数的默认值getClasses()似乎会有所不同,具体取决于getClasses()是在标准 R 函数中调用还是在正式 S4 方法中调用。它被.externalCallerEnv()哪个似乎是惰性评估的“对象”控制,从而导致变化(见下面的编辑

问题

从正式的 S4 方法内部调用时,如何设置与在标准函数内部调用where时的默认值相同的值?getClasses()


插图

您将在下面找到上述“问题行为”的简短说明

1) 自定义类

我有许多当前来自.GlobalEnv.

让我们以这一个作为他们所有人的代表

2)列出可用的类

通过 argument where, functiongetClasses让我选择寻找类的环境。

以下似乎无处不在.GlobalEnv,因此找不到我的班级;没关系:

现在我只.GlobalEnv查找类A;这也很好:

3) 创建自定义标准查找函数

当我将查找通过getClasses放入标准函数中时(这只是所需功能的第一部分,我想getClasses()在该方法内部进行计算,而不是将其返回值作为形式参数传递),一切仍然正常

4) 创建正式的 S4 方法

但是,一旦我将所有内容都放入正式的 S4 方法getClasses()中,用于查找类的标准环境似乎发生了一些变化

以前,"A" %in% foo1(where=NULL)FALSE需要),而现在是("A" %in% foo2(where=NULL)不需要TRUE

任何想法如何foo2()以完全相同的方式表现foo1()


编辑 2012-08-29

正如 Josh O'Brien 在下面的评论中指出的那样,这种变化可能是由惰性评估引起的。

调试foo1()

你进入调试跟踪器;点击<RETURN> 4 次,然后输入get("where")

在控制台中,点击<RETURN> 1 次,然后键入evList

键入Q以退出当前调试运行

现在再次运行所有内容,但调试调用略有不同

在控制台中,点击<RETURN> 5 次,然后键入evList

现在输入get("where")

现在where指向namespace:methods

调试`foo2()'

你进入调试跟踪器;点击<RETURN> 4 次,然后输入get("where")

然后点击<RETURN> 1 次,然后键入evList

键入Q以退出当前调试运行

现在再次运行所有内容,但调试调用略有不同

点击<RETURN> 5 次,然后输入evList

现在输入get("where")

evList并注意与where之前的调试运行相比的不同值。键入Q以退出当前调试运行。

这对我来说似乎有些奇怪,但从语言设计者的角度来看可能是有道理的。一旦我知道如何显式设置where为指向与namespace:methods.

0 投票
3 回答
1137 浏览

emacs - Emacs 中的词法作用域:与旧版 Emacsen 的兼容性

Emacs 24 为局部变量添加了可选的词法绑定。我想在我的模块中使用这个功能,同时保持与 XEmacs 和以前的 Emacs 版本的兼容性。

在 Emacs 24 之前,获得闭包的最简单方法是使用 中lexical-let定义的形式cl-macs,它通过一些巧妙的宏技巧来模拟词法范围。虽然这在 elisp 程序员中从未如此流行,但它确实有效,创建了真正有效的闭包,只要你记得将它们包装在 中lexical-let,就像在这个伪代码中一样:

问题是:在保留对 Emacs 23 和 XEmacs 的支持的同时,使用新的词法绑定的最佳方式是什么?目前,我通过定义一个特定于包的宏来解决它,该宏根据是否绑定和为真扩展lexical-let为普通宏:letlexical-binding

这个解决方案有效,但感觉很笨拙,因为新的特殊形式不标准,不能正确突出显示,不能进入 under edebug,并且通常会引起注意。有没有更好的办法?


编辑

两个更智能(不一定是好的)解决方案的想法示例,允许代码继续使用标准表单来创建闭包:

  • 使用建议或编译器宏来lexical-let扩展至仅当仅分配给let在词法范围内的符号时。这个建议只会在 的字节编译期间被临时激活,因此对于 Emacs 的其余部分来说,它的含义保持不变。lexical-bindingslexical-letfoo.ellexical-let

  • 使用宏/code-walker 工具将let非前缀符号编译到lexical-let较旧的 Emacsen 下。这将再次仅适用于foo.el.

如果这些想法带有过度设计的味道,请不要惊慌:我不建议按原样使用它们。我对上述宏的替代方案感兴趣,其中包获得了更好的可移植使用闭包的好处,代价是加载/编译的一些额外复杂性。


编辑 2

由于没有人采取一种解决方案来允许模块在 Emacs 的其余部分继续使用letlexical-let不破坏它们,我接受 Stefan 的回答,其中指出上述宏实现它的方法。除此之外,答案通过使用bound-and-true-p和添加 edebug 和 lisp-indent 的优雅声明来改进我的代码。

如果有人对此兼容层有替代建议,或者上述想法的优雅实现,我鼓励他们回答。

0 投票
1 回答
1775 浏览

javascript - Javascript 中存在哪些类型的范围?

我知道有全局范围,还有可嵌套的功能范围。但是 Javascript 中还有其他类型的作用域或闭包吗?

当我们讨论这个话题时,范围和闭包之间有什么区别?

0 投票
1 回答
1278 浏览

javascript - 从 jQuery.getJSON 返回一个 JSON blob

我有一个函数,我正在调用一个返回 JSON blob 的 MVC 控制器,其中包含一些后端操作的内容。此 JSON blob 用于填充呈现给最终用户的表。

我的功能目前看起来像这样:

...还有一个如下所示的调用动作:

当我运行调用它的网页/操作时,我会按照给定的顺序得到以下结果:

我尝试了一些其他配置(.getJSON() 的 .complete,直接从 $.getJSON() 返回一个值)以尝试将回调中的“数据”回显到封闭范围的 blob 变量,但到目前为止,该 blob 似乎仅在 getJSON 回调中具有价值。

话虽如此,我也知道 JavaScript 是一种词法范围的语言,所以它可能是所有匿名函数链正在执行的问题。

问题:我可以看到我的 blob 在 $.getJSON 中正确显示。现在,我该如何取出我的斑点?

0 投票
4 回答
170 浏览

javascript - 如果没有块范围,独立块的意义何在?

您可以使用这样的独立积木......

这来自:http ://eloquentjavascript.net/chapter3.html#p3c7ae609

但是有这样的块有什么意义呢?它的用途是什么?

0 投票
1 回答
1384 浏览

scheme - 就 SICP 的评估环境模型而言,词法与动态范围

在SICP 的第 3.2.2 节中,执行以下代码

用这张图来解释。

每次应用函数时,都会创建一个新框架(由E1through标记E4),它表示符号和值之间的一组绑定。当符号未绑定在框架中时,将查询该框架的封闭环境以获取该特定符号的绑定。

该图的有趣之处在于,所有标记为 的帧E都包含在全局环境中。文中解释说这是因为函数是在全局环境中定义的,但没有详细说明这个问题:

请注意,由 所创建的每个帧都square指向全局环境,因为这是square过程对象所指示的环境。

相反,如果框架包含在调用函数的环境中,比如E3包含在E2其中,又包含在 中E1,那么这是否是动态范围语言如何工作的有效模型?此外,图中的框架是否具有相同的“父”环境,因为 Scheme 是词法范围的?