全局作用域
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title></title>
</head>
<body>
<script type="text/javascript">
//全局作用域
var a = 2;
function add(){
var b = 3;
console.log(a);
}
console.log(b);
</script>
</body>
</html>
函数作用域
内部作用域原理 编译 执行 查询 嵌套 异常
案例体现作用域内部原理过程
<script>
function fn(a){
console.log(a);
}
fn(2);
</script>
词法作用域
<script>
function foo(a){
var b = a * 2;
function bar(c){
console.log(a,b,c);
}
bar(b*3);
}
foo(2);
</script>
遮蔽
作用域查找从运行时所处的最内部的作用域开始,逐级向上进行,直到遇到第一个匹配的标识符为止
多层的嵌套作用域中可以定义同名的标识符,这叫做遮蔽效应。
<script>
var a = 0;
function test(){
var a = 1;
console.log(a);
}
test();
</script>
变量的声明提升
<script>
//边解释边执行
//预解释
a = 2;
var a;
console.log(a);
</script>
声明从他们从代码中出现的位置被移动到最上面,这个过程叫做变量的提升,也叫预解释
<script>
var a;
console.log(a);
a = 2;
</script>
函数声明的提升
<script>
foo();
function foo(){
console.log('xx');
}
//函数声明不会提升
var foo = function foo(){
console.log(1);
}
</script>
声明注意事项
在js中声明分为变量声明和函数声明
变量的声明优先于函数的声明,但是函数的声明会覆盖未定义的同名的变量
<script>
var a = 10;
function a(){
};
console.log(a);
</script>
变量的重复声明是无用的,但是函数的重复声明会覆盖前面的声明功能(无论是变量还是函数声明)
作用域链和自由变量
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title></title>
</head>
<body>
<script type="text/javascript">
var a = 1;
var b = 2;
function fn(x){
var a = 10;
function bar(x){
var a = 100;
b = x + a;
return b;
}
bar(20);
bar(200);
}
</script>
</body>
</html>
bar---->fn ---->全局
自由变量:在当前作用域中存在但未在当前作用域中声明的变量。
一旦出现自由变量就肯定会有作用域链!然后我们根据作用域链查找机制来查找到对应的变量。
作用域链的查找机制
查找机制:在当前作用域中发现没有该变量,然后沿着作用域链查找,直到查找到对应的变量为止,如果查找不到,直接报错。
执行环境也叫执行的上下文,我们叫它执行上下文环境。
每个执行环境都有一个与之关联的变量对象,环境中定义的函数和变量都保存在这个对象中。
执行环境栈
每个方法在调用的时候会把执行环境压入到栈中。执行环境栈其实就是方法压栈和出栈的内容。