javascript中变量的范围是什么?它们在函数内部的作用域与在函数外部的作用域相同吗?或者这有关系吗?此外,如果变量是全局定义的,那么变量存储在哪里?
当前回答
1) 有一个全局作用域、一个函数作用域以及with和catch作用域。一般来说,变量的作用域没有“块”级别的作用域——with和catch语句为其块添加名称。
2) 作用域一直由函数嵌套到全局作用域。
3) 通过原型链解决财产问题。with语句将对象属性名称带入with块定义的词法范围。
编辑:ECMAAScript 6(Harmony)被指定为支持let,我知道chrome允许一个“和谐”标志,所以也许它确实支持它。。
这将是对块级范围的支持,但必须使用关键字才能实现。
编辑:根据本杰明在评论中指出的with和catch语句,我编辑了帖子,并添加了更多内容。with和catch语句都将变量引入到各自的块中,这是一个块范围。这些变量是传递给它们的对象的财产的别名。
//chrome (v8)
var a = { 'test1':'test1val' }
test1 // error not defined
with (a) { var test1 = 'replaced' }
test1 // undefined
a // a.test1 = 'replaced'
编辑:澄清示例:
test1的作用域为with块,但别名为a.test1Vartest1'在上层词法上下文(函数或全局)中创建一个新的变量test1,除非它是一个属性——它就是这样。
诶呀小心使用'with'——就像var是noop一样,如果变量已经在函数中定义,那么它也是从对象导入的名称的noop!对已经定义的名称稍加注意会使其更加安全。因此,我个人永远不会使用。
其他回答
ECMAScript 6引入了let和const关键字。这些关键字可以用来代替var关键字。与var关键字相反,let和const关键字支持在块语句中声明局部范围。
var x = 10
let y = 10
const z = 10
{
x = 20
let y = 20
const z = 20
{
x = 30
// x is in the global scope because of the 'var' keyword
let y = 30
// y is in the local scope because of the 'let' keyword
const z = 30
// z is in the local scope because of the 'const' keyword
console.log(x) // 30
console.log(y) // 30
console.log(z) // 30
}
console.log(x) // 30
console.log(y) // 20
console.log(z) // 20
}
console.log(x) // 30
console.log(y) // 10
console.log(z) // 10
1) 有一个全局作用域、一个函数作用域以及with和catch作用域。一般来说,变量的作用域没有“块”级别的作用域——with和catch语句为其块添加名称。
2) 作用域一直由函数嵌套到全局作用域。
3) 通过原型链解决财产问题。with语句将对象属性名称带入with块定义的词法范围。
编辑:ECMAAScript 6(Harmony)被指定为支持let,我知道chrome允许一个“和谐”标志,所以也许它确实支持它。。
这将是对块级范围的支持,但必须使用关键字才能实现。
编辑:根据本杰明在评论中指出的with和catch语句,我编辑了帖子,并添加了更多内容。with和catch语句都将变量引入到各自的块中,这是一个块范围。这些变量是传递给它们的对象的财产的别名。
//chrome (v8)
var a = { 'test1':'test1val' }
test1 // error not defined
with (a) { var test1 = 'replaced' }
test1 // undefined
a // a.test1 = 'replaced'
编辑:澄清示例:
test1的作用域为with块,但别名为a.test1Vartest1'在上层词法上下文(函数或全局)中创建一个新的变量test1,除非它是一个属性——它就是这样。
诶呀小心使用'with'——就像var是noop一样,如果变量已经在函数中定义,那么它也是从对象导入的名称的noop!对已经定义的名称稍加注意会使其更加安全。因此,我个人永远不会使用。
JavaScript只有两种类型的作用域:
全局作用域:全局只是一个窗口级作用域。在这里,整个应用程序中都存在变量。Functional Scope:在带有var关键字的函数中声明的变量具有函数作用域。
每当调用一个函数时,就会创建一个变量范围对象(并包含在范围链中),然后是JavaScript中的变量。
a = "global";
function outer(){
b = "local";
console.log(a+b); //"globallocal"
}
outer();
作用域链-->
窗口级别-a和外部函数位于范围链的顶层。当外部函数调用一个新的变量作用域对象(并包含在作用域链中)时,在其内部添加了变量b。
现在,当一个变量a需要时,它首先搜索最近的变量范围,如果变量不在,则将其移动到变量范围链的下一个对象。在这种情况下,这是窗口级别。
最初由Brendan Eich设计的JavaScript中的作用域概念来自HyperCard脚本语言HyperTalk。
在这种语言中,显示类似于一堆索引卡。有一张主卡被称为背景。它是透明的,可以看作是底牌。此基础卡上的任何内容都与放在其上面的卡共享。放在上面的每张卡都有自己的内容,这些内容优先于前一张卡,但如果需要,仍然可以访问前一张卡片。
这正是JavaScript作用域系统的设计方式。它只是有不同的名字。JavaScript中的卡片称为Execution ContextsCMA。这些上下文中的每一个都包含三个主要部分。变量环境、词汇环境和此绑定。回到卡片参考,词汇环境包含堆栈中较低的先前卡片的所有内容。当前上下文位于堆栈的顶部,其中声明的任何内容都将存储在变量环境中。在命名冲突的情况下,变量环境将优先。
此绑定将指向包含对象。有时,作用域或执行上下文在包含对象不变的情况下发生变化,例如在声明的函数中,包含对象可能是窗口或构造函数。
这些执行上下文是在任何时候传输控制时创建的。当代码开始执行时,控制权被转移,这主要是通过函数执行完成的。
这就是技术解释。在实践中,记住在JavaScript中
范围在技术上是“执行上下文”上下文形成存储变量的环境堆栈堆栈的顶部优先(底部是全局上下文)每个函数都创建一个执行上下文(但不总是一个新的此绑定)
将此应用于前面的一个示例(5。“闭包”),可以遵循执行上下文的堆栈。在本例中,堆栈中有三个上下文。它们由外部上下文、var six调用的立即调用函数中的上下文以及var six立即调用函数内部返回函数的上下文定义。
i) 外部上下文。它的可变环境为a=1ii)IIFE上下文,它有一个a=1的词法环境,但一个a=6的变量环境在堆栈中优先iii)返回的函数上下文,它具有a=6的词法环境,这是调用时警报中引用的值。
据我理解,关键是Javascript具有函数级作用域,而不是更常见的C块作用域。
这是一篇关于这个主题的好文章。
推荐文章
- Javascript和regex:分割字符串并保留分隔符
- 如何检查DST(日光节约时间)是否有效,如果是,偏移量?
- 如何打破_。在underscore.js中的每个函数
- 如何在jQuery中获得当前日期?
- 如何创建一个日期对象从字符串在javascript
- 输入触发器按钮单击
- 获取对象的属性名
- 如何检查用户是否可以回到浏览器历史
- 相当于字符串。jQuery格式
- 如何在vue-cli项目中更改端口号
- Angular 2模板中的标签是什么意思?
- JavaScript .includes()方法的多个条件
- 窗口。亲近与自我。close不关闭Chrome中的窗口
- 同步和异步编程(在node.js中)的区别是什么?
- 在d3.js中调整窗口大小时调整svg的大小