作用域
javascript中有个作用域的概念。
- 全局作用域
- 函数作用域
作用域取决于函数定义的地方,与函数执行无关。
function F1() { var a = 100; return function () { console.log(a) } } var f1 = F1(); var a = 200; f1()
这段代码打印结果: 100; 我们这样来看,
F1定义的时候,作用域已经生成。
然后,把F1 赋值给 f1, 此时,f1 是一段函数,如下:
function() {
console.log(a)
}
然后,定义了一个全局变量a,在全局环境去执行f1.
注意: 作用域取决于函数定义的地方,与函数执行无关。
此时f1执行,去找a的变量,F1的局部作用域去找。
他会找到a = 100; 而不是a=200;
作用域是分层的,内层作用域可以访问外层作用域的变量,反之则不可以
作用域与执行上下文的区别:
开发人员很容易混淆作用域和执行上下文的概念,误认为他们是相同的概念,但事实并非如此。
js属于解释型语言,js的执行行为分为:解释和执行两个阶段
解释阶段:
- 词法分析
- 语法分析
- 作用域规则确定
执行阶段:
- 创建执行上下文
- 执行函数代码
- 垃圾回收
js解释阶段便会确定作用域的规则,因此作用域在函数定义时就已经确定了,而不是在函数调用时确定,但执行上下文是函数执行之前创建的。执行上下文最明显的就是this指向是执行时确定的。而作用域访问的变量是编写代码的结构确定的。
执行上下文和作用域最大的区别是:执行上下文在运行时确定,随时可能该变;作用域在定义时就确定,并且不会改变。
一个作用域下可能包含若干个上下文环境。有可能从来没有过上下文环境(函数从来就没有被调用过);有可能有多,现在函数被调用完毕后,上下文环境被销毁了;有可能同时存在一个或者多个闭包。同一个作用域下,不同的调用会产生不同的执行上下文环境,继而产生不同的变量值。
更详细可以查看:https://www.jianshu.com/p/38b18f6ceec5