作用域

词法作用域

作用域

表示的就是范围,即作用范围

  • 就是一个名字在什么地方能使用,在什么地方不能使用

块级作用域

级别的作用范围

    // 在 c , java 等编程语言中,下面的语法报错
{
var num = 123; // 应该用int , 这里是伪代码
{
console.log(num); // 123
}
console.log(num); // 报错
}

在 js 中采取词法作用域

词法(代码)作用域,就是代码在编写过程中体现出来的作用范围,代码一旦写好,不用执行,他的作用范围就已经确定好了,这个就是所谓的词法作用域

在 js 中的词法作用域规则

1. 函数允许方位函数外的数据

2. 整个代码结构中只有函数可以限定作用域

3. 作用规则首先是提升规则分析

4. 就近原则如果当前作用规则有了名字,就不考虑外面的名字

在 js 中作用域分析方法

1. 先进行预解析,分析预解析过程
* 程序在执行过程, 会先将代码读取到内存中检查. 会将所有的声明在此时进行标记. 所谓的标记就是
让 js 解释器知道有这个名字, 后面在使用名字的时候, 不会出现未定义的错误. 这个标记过程就是提升.
* 声明
1. 名字的声明, 标识符的声明( 变量名声明 )
* 名字的声明就是让我们的解释器知道有这个名字
* 名字没有任何数据与之对应
2. 函数的声明
* 函数声明包含两部分
* 函数声明与函数表达式有区别, 函数声明是单独写在一个结构中, 不存在任何语句, 逻辑判断等结构中
* 首先函数声明告诉解释器有这个名字存在. 该阶段与名字声明一样
* 告诉解释器, 这个名字对应的函数体是什么**(函数名和函数体绑定链接)**
2. 再进行代码执行过程

常见的简单作用域问题

例子 1:

    var num = 123;
function foo(){
console.log(num);
}
foo(); // 输出 123
  1. 代码执行

例子 2:

    if(false){
var num = 123;
}
console.log(num); // 输出undefined
  1. 执行代码

例子 3:

    var num = 123;
function foo(){
var num = 456;
function fn(){
console.log(num); // 输出456
};
fn();
}
foo();
  1. 执行代码

例子 4:

    var num = 123;
function foo1(){
var num = 456;
function foo2(){
num = 789;
function foo3(){
console.log(num); // 输出789
}
foo3();
}
foo2();
}
foo1(); // 输出456
console.log(num); // 输出123
  1. 执行代码

例子 5:

    if ( ! 'a' in window ) {
var a = 123;
}
console.log( a ); // undefined
  1. 执行代码

复杂的作用域问题

例子 1

    if ( true ) {
function f1 () {
console.log( 'true' );
}
} else {
function f1 () {
console.log( 'false' );
}
}
f1();
  1. 执行代码

旧版浏览器

  1. 预解析
  1. 执行代码

例子 2

    if ( false ) {
function f1 () {
console.log( 'true' );
}
} else {
function f1 () {
console.log( 'false' );
}
}
f1();
  1. 执行代码

旧版浏览器

  1. 预解析
  1. 执行代码

例子 3

    var num = 123;
function f1() {
console.log( num );
}
function f2() {
var num = 456;
f1();
}
f2();
  1. 执行代码

例子 4

    var num = 123;
function f1() {
console.log( num );
}
function f2() {
num = 456;
f1(num);
}
f2();
  1. 代码执行
05-27 10:37