作用域
就是变量的有效范围。在一定的空间里可以对数据进行读写操作,这个空间就是数据的作用域
1、全局作用域:最外层函数定义的变量拥有全局作用域,即对任何内部函数来说,都是可以访问的;
1、全局作用域:局部作用域一般只在固定的代码片段内可访问到,而对于函数外部是无法访问的,最常见的例如函数内部。在ES6之前,只有函数可以划分变量的作用域,所以在函数的外面无法访问函数内的变量
3、块级作用域:凡是代码块就可以划分变量的作用域,这种作用域的规则就叫块级作用域
块级作用域 函数作用域 词法作用域之间的差异:
区别
- 块级作用域和函数作用域描述的是,什么东西可以划分变量的作用域
- 词法作用域描述的是,变量的查找规则
关系
- 块级作用域 包含 函数作用域
- 词法作用域 与 块级作用域、函数作用域之间没有任何交集,他们从两个角度描述了作用域的规则
ES6 之前 JavaScript 采用的是函数作用域+词法作用域,ES6 js 采用的是块级作用域+词法作用域
预解析
JavaScript 代码的执行是由浏览器中的 JavaScript 解析器来执行的。JavaScript 解析器执行JavaScript 代码的时候,分为两个过程:预解析过程和代码执行过程
预解析过程
- 把变量的声明提升到当前作用域的最前面,只会提升声明,不会提升赋值
- 把函数的声明提升到当前作用域的最前面,只会提升声明,不会提升调用
- 先提升 var,再提升 function
示例1:
var a = 25;
function abc() {
alert(a);
var a = 10;
}
abc();
以上代码弹出undefined
示例2:
console.log(a);
function a() {
console.log('aaaaa');
}
var a = 1;
console.log(a);
以上代码输出:
ƒ a() {
console.log('aaaaa');
}
1
变量提升
变量提升:定义变量的时候,变量的声明会被提升到作用域的最上面,变量的赋值不会提升
函数提升:JavaScript 解析器首先会把当前作用域的函数声明提前到整个作用域的最前面
示例3:
var num = 10;
fun();
function fun(){
console.log(num);
var num = 20;
}
以上代码输出undefined
示例4:
var a = 18;
f1();
function f1(){
var b = 9;
console.log(a);
console.log(b);
var a = '123';
}
以上代码输出:
undefined
9
示例5:
f1();
console.log("c" + c);
console.log("b" + b);
console.log("a" + a);
function f1() {
var a = b = c = 9;
console.log("aa" + a);
console.log("bb" + b);
console.log("cc" + c);
}
以上代码输出
aa9
bb9
cc9
c9
b9
Uncaught ReferenceError: a is not defined // 最后一行报错
上面最后一行报错的原因是:
var a = b = c = 9;
相当于c = 9; b = c; var a = b
,其中c
和b
为隐式声明,a
为var
显示声明.在函数内部显示声明的变量为局部变量,隐式声明的变量为全局变量,所以全局变量c
和b
在函数外可以访问到,而局部变量a
在函数外访问不到
把以上代码改为下面这样,可以正常执行
f1();
console.log("c" + c);
console.log("b" + b);
console.log("a" + a);
function f1() {
a = b = c = 9;
console.log("aa" + a);
console.log("bb" + b);
console.log("cc" + c);
}
输出为:
aa9
bb9
cc9
c9
b9
a9
网友评论