美文网首页Web前端之路让前端飞饥人谷技术博客
用几个demo帮助理解JS作用域链和声明前置

用几个demo帮助理解JS作用域链和声明前置

作者: fanlelee | 来源:发表于2019-12-07 23:38 被阅读0次

声明前置

  • 变量的声明前置:指在变量被定义时,会在代码执行之前将变量放在最前面进行初始化。
  • 函数的声明前置:会将函数声明放在代码执行之前先去生成该函数,所以函数声明受到函数提升机制的影响,所以无论放在什么位置都可以被调用。

作用域

  1. 每当声明一个新的函数就进入一个新的作用域下;
  2. 函数里需要用到的变量(或函数)首先会在自身作用域下找,找不到再逐级向上层作用域去找。

作用域链查找过程伪代码

  1. 分析代码,首先可根据提升机制将变量或者函数编译在最前面;
  2. 写出作用域链查找过程伪代码,找到每个作用域的AOScope
  3. 根据伪代码方可分析出具体结果。

举例说明

  1. 变量的声明前置
    console.log(a);//undefined
    var a = 1;
    console.log(a);//1
    /* 声明前置分析代码 */
    var a
    console.log(a)//undefined
    a = 1
    console.log(a)
    //变量a会声明前置,故第一次输出:undefined
    //第二次输出前变量a已经赋值,故第二次输出:1
  1. 函数声明放在任何位置都会函数声明前置,而函数表达式只有在这个表达式执行完后才会调用改函数
    sayName('world');
    sayAge(10);
    function sayName(name){
        console.log('hello ', name);
    }
    var sayAge = function(age){
        console.log(age);
    };
/* 首先还是根据函数提升机制分析代码 */
    function sayName(){...}
    var sayAge
    sayName('world')   //输出:hello world
    sayAge(10)        //输出:sayAge is not a function
    sayAge = function(){..}
    var x = 10
    bar() 
    function foo() {
      console.log(x)
    }
    function bar(){
      var x = 30
      foo()
    }
/* 首先根据声明前置分析代码 */
    var x
    function foo(){
        console.log(x)
    }
    function bar(){
        var x
        x = 30
        foo()
    }
    x = 10
    bar()

/* 作用域链查找过程伪代码 */
    globalContext{
        AO:{
            x:10
            foo:function
            bar:function
        }
        Scope:{}
    }
    foo[[scope]] = globalContext.AO
    bar[[scope]] = globalContext.AO

    fooContext{
        AO:{}
        Scope:foo[[scope]] = globalContext.AO
    }

    barContext{
        AO:{
            x:30
        }
        Scope:bar[[scope]] = globalContext.AO
    }

//输出: 10
    var x = 10;
    bar() 
    function bar(){
      var x = 30;
      function foo(){
        console.log(x) 
      }
      foo();
    }
/* 作用域链查找过程伪代码 */
    globalContext{
        AO:{
            x:10,
            bar:function
        },
        Scope:{}
    }
    bar[[scope]] = globalContext.AO

    barContext{
        AO:{
            x:30,
            foo:function
        }
        scope:bar[[scope]] = globalContext.AO
    }
    foo[[scope]] = barContext.AO

    fooContext{
        AO:{}
        scope:barContext.AO
    }

    //输出:30
    var a = 1;

    function fn(){
      console.log(a)
      var a = 5
      console.log(a)
      a++
      var a
      fn3()
      fn2()
      console.log(a)

      function fn2(){
        console.log(a)
        a = 20
      }
    }

    function fn3(){
      console.log(a)
      a = 200
    }

    fn()
    console.log(a)
/* 作用域链查找过程伪代码 */
    globalContext{
        AO:{
            a:1->200
            fn:function,
            fn3:function
        },
        Scope:{}
    }
    fn[[scope]] = globalContext.AO
    fn3[[scope]] = globalContext.AO

    fnContext{
        AO:{
            a:5->6->20
            fn2:function
        }
        scope:globalContext.AO
    }
    fn2[[scope]] = fnContext.AO

    fn3Context{
        AO:{}
        scope:globalContext.AO
    }

    fn2Context{
        AO:{}
        scope:fnContext.AO
    }


    //输出: undefined 5 1 6 20 200

相关文章

  • 用几个demo帮助理解JS作用域链和声明前置

    声明前置 变量的声明前置:指在变量被定义时,会在代码执行之前将变量放在最前面进行初始化。 函数的声明前置:会将函数...

  • zj3 函数与作用域

    讲解函数声明、函数表达式、声明前置、作用域、作用域链相关概念 函数声明和函数表达式有什么区别 什么是变量的声明前置...

  • JS作用域链和声明前置的理解

    例题: 例题中的作用域链: console.log('1.'+a):在JS中的语句var a = 1其实是两条语句...

  • JS作用域的练习

    Js作用域练习demo1 Js作用域练习demo2 JS作用域练习demo3 JS作用域练习demo4 JS作用域...

  • JavaScript 函数闭包(colsure)

    理解闭包,你首先必须理解JS的变量作用域,JavaScript作用域和作用域链。 ES6之前,变量的作用域分为全局...

  • 3小时速学JS原理

    内容:前端JS部分知识点原理速讲,内容包括且不限于 声明前置 引用类型 函数作用域链 闭包 跨域 面向对象 继承 ...

  • 总结篇(四) -- 进阶

    概述 本篇主要讲述声明前置、引用类型、函数作用域链、闭包、HTTP、Web安全和性能优化 声明前置 在进入一个执行...

  • JS博客

    JS构造函数及new运算符 JS原型对象和原型链 函数作用域和作用域链 干货分享:让你分分钟学会JS闭包 深入理解...

  • 前端基础(问答12)

    keywords:函数声明、函数表达式、声明前置、argument、重载、作用域链 函数声明和函数表达式有什么区别...

  • 函数&声明前置&作用域链

    1. 函数声明和函数表达式有什么区别 JavaScript函数是指一个特定代码块,可能包含多条语句,可以通过名字来...

网友评论

    本文标题:用几个demo帮助理解JS作用域链和声明前置

    本文链接:https://www.haomeiwen.com/subject/kfmpgctx.html