• 作用域 {#作用域}
    • 执行上下文
    • 作用域
    • 如何理解作用域
  • 变量作用域
    • 静态作用域
    • 动态作用域
  • JS变量作用域
    • 作用域链
      • 对变量提升的理解
      • 创建10个<a>标签 点击的时候弹出来对应的序号

    作用域 {#作用域}

    执行上下文

    1. console.log(a); // undefined
    2. var a = 100;
    3. fn('zhangsan') // 'zhangsan' 20
    4. function fn(name) {
    5. age = 20;
    6. console.log(name, age);
    7. var age;
    8. }
    • 范围:一段<script>或者一个函数
    • 全局:变量定义、函数声明
    • 函数:变量定义、函数声明、this、arguments
    • 注意⚠️“函数声明”和“函数表达式”的区别
    1. fn()
    2. function fn() {
    3. //声明
    4. }
    5. fn1()
    6. var fn1 = function () {
    7. //表示
    8. }
    9. var a = 100; //类似于这个
    10. //全局声明
    11. console.log(a);
    12. var a = 100;
    13. fn('zhangsan')
    14. function fn(name) {
    15. console.log(this);
    16. age = 20;
    17. console.log(name,age);
    18. var age;
    19. bar(100);
    20. function bar(num) {
    21. console.log(num);
    22. }
    23. }

    作用域

    • 没有块级作用域
    • 只有函数和全局作用域
    1. //无块级作用域
    2. if(true){
    3. var name = 'zhangsan';
    4. }
    5. console.log(name);
    6. //函数和全局作用域
    7. var a = 100;
    8. function fn() {
    9. var a = 200;
    10. console.log('fn',a);
    11. }
    12. console.log('global',a);
    13. fn();

    如何理解作用域

    • 自由变量
    • 作用域链,即自由变量的查找
    • 闭包的两个场景
    1. var x=10;
    2. function foo() {
    3. alert(x);
    4. }
    5. function bar() {
    6. var x=20;
    7. foo();
    8. }
    9. bar();
    • 生命周期
    • 作用范围

    变量作用域

    • 静态作用域
    • 动态作用域

    静态作用域

    • 被称为词法作用域
    • 由程序定义位置决定
    1. var x=10;
    2. function foo() {
    3. alert(x);
    4. }
    5. function bar() {
    6. var x=20;
    7. foo();
    8. }
    9. bar();

    全局作用域
    x 10
    foo
    bar

    foo作用域
    - -

    bar作用域
    x 20

    动态作用域

    • 程序运行时刻
    • 栈操作

    x:20
    bar:
    foo:

    JS变量作用域

    • JS使用静态作用域
    • JS没有块级作用域(全局作用域、函数作用域)(ES5)
    • ES5中使用词法环境管理静态作用域
    1. var x = 10;
    2. function foo() {
    3. var z = 30;
    4. function bar(q) {
    5. return x + y + q;
    6. }
    7. return bar;
    8. }
    9. var bar = foo(20);
    10. bar(40);
    • 环境记录
      • 形式参数
      • 函数声明
      • 变量
    • 对外部词法环境的引用(outer)

    • 初始化

    作用域 - 图1


    • 执行

    作用域 - 图2


    作用域链

    1. var a = 100;
    2. function fn() {
    3. var b = 200;
    4. //作用域没有定义变量,即“自由变量”
    5. console.log(a);
    6. console.log(b);
    7. }
    8. fn();
    9. var a = 100;
    10. function F1() {
    11. var b = 200;
    12. function F2() {
    13. var c = 300;
    14. console.log(a);//a是自由变量。形成一个链式结构,向父级去查找
    15. console.log(b);//b是自由变量
    16. console.log(c);//
    17. }
    18. }

    对变量提升的理解

    • 变量定义
    • 函数声明(注意和函数表达式的区别)

    创建10个<a>标签 点击的时候弹出来对应的序号

    • 错误写法
    1. //这是一个错误的写法!!!
    2. var i,a;
    3. for (var i = 0; i < 10; i++) {
    4. a = document.createElement('a');
    5. a.innerHTML = i + '<br>';
    6. a.addEventListener('click',function (e) {
    7. e.preventDefault();
    8. alert(i)
    9. })
    10. document.body.appendChild(a);
    11. }
    12. //输出为如下: <a>"9"<br></a>
    • 正确写法
    1. //这是一个正确写法!!!
    2. var i;
    3. for (i = 0; i < 10; i++) {
    4. (function(i){
    5. var a = document.createElement('a');
    6. a.innerHTML = i + '<br>';
    7. a.addEventListener('click',function (e) {
    8. e.preventDefault();
    9. alert(i);
    10. })
    11. document.body.appendChild(a);
    12. })(i)
    13. }