美文网首页
js作用域、作用域链、闭包

js作用域、作用域链、闭包

作者: 仔崽06 | 来源:发表于2021-02-04 14:21 被阅读0次

作用域

1.javascript局部作用域

变量在函数内部声明,变量为局部作用域.

//局部变量:只能在函数内部访问
function test(){
   var name='zdb'
}
console.log(name) //undefined

2.javascript全局变量

//全局变量:函数内部外部都可以访问
var name='zdb'
function test(){
  console.log(name) //zdb
}
test()

3.隐式声明

//函数内部没有使用var 声明的变量 会默认认为是全局变量
function test(){
   name='zdb'
}
console.log(name) //zdb

[[scope]]作用域

每个javascript函数都是一个对象,对象中有的属性可以访问,有的属性仅供javascript引擎存取[[scope]]就是其中一个,指的是作用域,其中存储了运行期上下文集合.

运行期上下文

当函数执行时,会创建一个称为执行期上下文的内部对象.一个执行期上下文定义了一个执行时的环境,函数每次执行时对应的执行上下文都是独一无二的,所以多次调用一个函数会导致创建多个执行上下文,当函数执行完毕,它所产生的上下文被销毁.

  • 代码示例
var  glob=1000
function test(){
   console.log('test')
}

1.test函数声明时,scope[0]里指向全局GO对象

image.png
var  glob=1000
function test(){
   var  b=123
   console.log(b) //123
}
test()

2.test函数执行时会创建一个独一无二的执行期上下文AO,形成作用域链,AO会默认排到作用域链的最顶端.

image.png
  1. test执行完毕会默认销毁自己的执行上下文AO,回到初始定义状态.
image.png
  • 代码示例
function a(){
    function b(){
        var bb=234
        aa=0
    }
    var aa=123;
    b();
    console.log(aa) //0
}
a()

1.a定义状态,scope[0]里指向全局GO对象

image.png

2.a函数执行创建自己的AO,会将自己的AO排到作用域链的最顶端,a执行的时候,定义b函数,b函数定义会自带a函数的AO、GO ,b函数与a函数,指向的是同一个AO.

image.png

3.a函数执行过程中,b函数定义被执行,b函数执行创建自己的AO,执行完毕销毁自己的AO,b函数里面查找aa变量统一在作用域链依次由上向下查找,自己的AO里没有找到aa变量,修改的变量aa是a函数AO对象的值.这时aa已被改为0,再次读取aa变量 值为0.

image.png

4.b函数执行完毕会销毁自己的AO回到初始状态,其次a函数执行完毕会销毁自己的AO回到初始状态.

  • 闭包

一个内层函数中访问到其外层函数的作用域.

  • 代码示例
function a(){
    function b(){
        var bbb=234;
        console.log(aaa) //123
    }
    var aaa=123;
    return b;
}
var glob=100;
var demo=a();
demo()

1.a被执行,b被定义时 并将b保存出到函数外部.

image.png

2.b函数执行时a函数已执行完毕,a函数会取消指向自己AO的引用,但是b函数还指向a函数的AO引用,b函数在自己执行时会创建自己的AO会默认排到作用域链的最顶端[0]位,b函数读取aaa变量默认会从作用域顶端依次向下查找,这时自己AO没有aaa,a函数的AO里有aaa所以查找结果为123

image.png
  • 立即执行函数

可以让函数在创建后立即执行.

  • 写法一
(function(){
    console.log(1)
}())
  • 写法二
(function(){
    console.log(2)
})()
  • 被执行符号执行的表达式,函数名没有意义
//此处函数名没有意义
(function test(){console.log(1)}())
console.log(test)  // test is not defined

let test=function demo(){
    console.log(11111)
}()
console.log(demo)// demo is not defined
  • 只有执行表达式才能被执行符号执行
function test(){
    console.log(1111)
}() //error:Unexpected token ')'

//执行符号 * /例外
+ function test(){
    console.log(1111)
}()  //1111

- function test(){
    console.log(1111)
}()  //1111

! function test(){
    console.log(1111)
}()  //1111
  • 如果调用传参不会执行,也不会报错
function test(a,b){
    console.log(a+b)
}(1,4)

//系统会识别成
function test(a,b){
    console.log(a+b)
}
(1,4)
  • 立即执行函数应用场景
//可以套用作用域链,梳理逻辑
function test(){
    var arr=[];
    for(var i=0;i<10;i++){
        arr[i]=function(){
            console.log(i) //10个10
        }
    }
    return arr
}
let myArr=test();
for(var i=0;i<myArr.length;i++){
    myArr[i]()
}

//利用自执行函数,生成作用域链
function test(){
    var arr=[];
    for(var i=0;i<10;i++){
        arr[i]=(function(j){
            return function (){
               console.log(j) //0,1,2,3,4,5,6,7,8,9
            }
      }(i))
    }
    return arr
}
let myArr=test();
for(var i=0;i<myArr.length;i++){
    myArr[i]()
}

相关文章

  • js 总结七07-19

    作用域 全局 局部 作用域链 闭包

  • JavaScript 函数闭包(colsure)

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

  • 2023-01-12

    变量提升调用栈块级作用域作用域链和闭包 闭包 => 作用域链(词法作用域) => 调用栈(栈溢出) => 上下文...

  • js作用域、闭包

    闭包 闭包作用 全局 局部 作用域链

  • 闭包

    一、理解闭包前js基础1、作用域链(作用域、作用域链中有说)。2、js的内存回收机制。一个函数在执行开始的时候,会...

  • 执行上下文,词法作用域,作用域链,闭包

    执行上下文,词法作用域,作用域链,闭包

  • 《Web前端开发之JavaScript精英课堂》(六)

    对 作用域、作用域链、执行上下文对象(GO | AO)、闭包 的个人理解: JS分为全局和局部作用域,都属于词法作...

  • js 闭包

    一、js 作用域 讲闭包首先就要理解 js 的作用域。再 ES5 中,js 有两种作用域,全局作用域和函数作用域(...

  • js函数中的this

    前两篇文章“执行环境和作用域”和“js中的闭包”,我对谈了执行环境、作用域、作用域链和闭包的理解。但当牵涉到对象中...

  • js闭包的理解

    什么是闭包 通俗的来讲,个人觉得闭包就是延长变量作用域的函数。众所周知js的作用域分为全局作用域和链式作用域。在函...

网友评论

      本文标题:js作用域、作用域链、闭包

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