Tomhsfreestyle 2019-06-28
JavaScript是门动态语言,跟Java不一样,JavaScript可以随意定义全局变量和局部变量,变量会在该作用域下提升,而且JavaScript没有块级作用域。
全局变量就是定义在全局的变量了,局部变量是定义在函数里的变量,每一个函数都是一个作用域,当函数执行时会优先查找当前作用域,然后逐级向上。定义在
if 和 for 语句里的变量,在大括号外面也能访问到,这就是没有块级作用域。
JavaScript 的作用域只用两种,一个是全局的,一个是函数的,也称为 全局作用域 和 局部作用域 ;局部作用域 可以访问 全局作用域 。但是 全局作用域 不能访问 局部作用域
有这样一段代码
var a = 1; function fn1(){ alert(a); var a = 2; } fn1(); alert(a);
这里先揭晓答案:
第一个 alert(a) 弹出 undefined 第二个 alert(a) 弹出 1
1. 预解析(预编译) 全局作用域 (全局词法环境)
// 全局词法环境 // 第1行,遇到 var 关键字,解析到全局的头部 a = undefined // 第2行,遇到 function 关键字,解析到全局的头部 fn1 = function fn1(){ alert(a); var a = 2; } // 第3行,没有遇到关键字,不解析 // 第4行,没有遇到关键字,不解析
2. 开始执行代码
第1行,遇到表达式 a = 1, a 被赋值成 1 第6行,遇到函数调用 fn1() , ---- 开始 预解析(预编译) 局部-----
3. 预解析(预编译) 局部作用域 (函数词法环境)
// 第3行,没有遇到关键字,不解析 // 第4行,遇到 var 关键字,解析到局部 a = undefined
4. 开始执行 局部 代码
第3行,弹出 undefined 第4行,遇到表达式,把局部 a 改成 2
5. 局部执行完成,继续执行全局
第7行,弹出 1 ,因为全局和局部是两个独立的作用域
1. js没有块作用域
2. js不是动态作用域,js是静态作用域
function f(){ alert(x); } function f1() { var x = 6; f(); } function f2() { var x = 10; f(); } f1(); // 执行会报错,因此js不是动态作用域哦
var a = 10; function f() { var x = 100; function g () { // } g(); } f();
1. 创建词法环境(window) 2. 加入 a 以及 f函数 ,这时候 【f.scope === window】 3. 进入f函数,创建f函数的词法环境 【f.le => f.scope】 4. 创建f 的词法环境 5. 添加x和 g函数 到f函数的词法环境 【g.scope === f.le】 6. 进入g函数,创建g函数的词法环境 【g.le => g.scope】
g.le -> g->scope -> f.le -> f.scope -> window
var a = 10; function f() { var x = 100; function g () { // alert(a); } g(); } f();
我们在g内部使用了变量a,想要找到a,
- 首先在g的词法环境中查找,如果没找到
- 到g.scope 也就是 f的词法环境中查找,如果依旧没找到
- 到f.scope 也就是 全局词法环境中查找。