函数编程-Javascript/EMMAScript中函数的作用域是什么
functional programming - What is the scope of a function in Javascript/ECMAScript?
今天我和一位同事讨论了Javascript中的嵌套函数:
function a() {
function b() {
alert('boo')
}
var c = 'Bound to local call object.'
d = 'Bound to global object.'
}
在这个例子中,试验指出,b在a的主体之外是不可到达的,就像c一样。然而,在执行a()之后,d是-。在ECMAScript v.3标准中寻找这种行为的确切定义,我没有找到我想要的确切措辞;第13节第71页没有说明的是,函数声明语句创建的函数对象要绑定到哪个对象。我遗漏了什么吗?
这是静态作用域。函数中的语句的作用域在该函数中。
然而,Javascript有一个奇怪的行为,即如果没有var关键字,您就隐含了一个全局变量。这就是你在测试中看到的。您的";d";变量是可用的,因为它是一个隐含的全局变量,尽管它是在函数体中编写的。
此外,为了回答问题的第二部分:函数存在于声明的任何范围中,就像变量一样。
旁注:你可能不想要全局变量,尤其是隐含变量。建议您始终使用var关键字,以防止混淆并保持一切清洁。
旁注:ECMA标准可能不是找到Javascript答案的最有用的地方,尽管它肯定不是一个坏资源。请记住,浏览器中的javascript只是该标准的实现,因此标准文档将为您提供javascript引擎构建时实现者(主要)遵循的规则。它不能提供有关您关心的实现(即主要浏览器)的具体信息。特别是有几本书将为您提供关于主流浏览器中javascript实现行为的非常直接的信息。为了说明差异,我将在下面摘录ECMAScript规范和一本关于Javascript的书。我想你会同意这本书给出了一个更直接的答案。
以下是ECMAScript语言规范:
10.2进入执行上下文
每个函数和构造函数调用进入新的执行上下文,甚至如果函数正在调用自己递归地。每次返回都会退出执行上下文。抛出的异常,如果没有被抓住,也可以退出一个或更多的执行上下文。
控制时输入执行上下文,范围链被创建和初始化,执行变量实例化,并且确定该值。
范围链的初始化,变量实例化,以及这个值的确定取决于取决于输入的代码类型。
以下是奥的Javascript:最终指南(第5版):
8.8.1词汇范围界定
JavaScript中的函数是词法上的而不是动态确定范围。这意味着它们在它们是定义的,而不是范围从中执行它们。当函数已定义,当前范围链被保存并成为函数的内部状态。…
强烈推荐Douglas Crockford的书:来回答这些问题
JavaScript,好的部分http://oreilly.com/catalog/covers/9780596517748_cat.gif
Javascript,The Good Parts,同样来自奥。
据我所知,就范围界定而言,这些是等效的:
function a() { ... }
和
var a = function() { ... }
需要注意的是,当d被创建为"全局"时,它实际上是作为窗口对象的属性创建的。这意味着您可能无意中覆盖了窗口对象上已经存在的内容,或者您的变量可能根本无法创建。因此:
function a() {
d = 'Hello World';
}
alert(window.d); // shows 'Hello World'
但你不能做:
function a() {
document = 'something';
}
因为无法覆盖window.document对象。
出于所有实际目的,您可以想象所有代码都在一个巨大的with(window)
块中运行。
Javascript有两个作用域。全局性和功能性。如果使用"var"关键字在函数内部声明一个变量,那么它将是该函数和任何内部函数的本地变量。如果在函数之外声明一个变量,那么它具有全局作用域。
最后,如果您在第一次声明变量时省略了var关键字,那么无论您在哪里声明它,javascript都会假设您想要一个全局变量。
因此,您正在调用函数a,而函数a正在声明一个全局变量d。
。。。
function a() {
function b() {
alert('boo')
}
var c = 'Bound to local call object.'
d = 'Bound to global object.'
}
如果前面没有var,d是全局的。将d私有化:
function a() {
function b() {
alert('boo')
}
var c = 'Bound to local call object.'
var d = 'Bound to local object.'
}
- 在Meteor中使用moment.tz.setDefault()时的作用域是什么
- JavaScript 中加号运算符的域是什么?
- JavaScript 中的范围(为什么在 $.post() 方法数组的作用域是本地的?)
- jqueryajax表单提交请求第一次点击不起作用可能是什么原因
- Javascript中的作用域是什么
- 为什么javascript函数的作用域是作为参数传递的'窗口'--以及如何使作用域成为其父类
- javascript中的作用域是如何工作的?为什么这个功能有效
- 我在另一个网站上的javascript,它检查cookie的域是什么
- 作用域是't更新$apply使用
- Javascript中的作用域是如何工作的
- Q承诺-作用域是如何工作的
- 什么时候应该使用继承作用域,什么时候不应该
- JavaScript跨域PHP调用中的Cookie域是什么
- access-control-allow-origin中的相同域是什么?
- 为什么angularjs的作用域是允许在初始化之前访问变量
- 我怎么能得到自己的范围在定义模块在require.js?作用域是'this'我希望它是模块本身
- 在严格模式下,函数表达式中定义的变量的作用域是什么?
- javascript、C和Python中if块中变量的作用域是什么?
- 在Javascript中,setTimeout中使用的变量的作用域是什么?
- 函数编程-Javascript/EMMAScript中函数的作用域是什么