05-javascript基础----js作用域

一、作用域

1. 概念 & 作用

作用域,就是一个代码块所在的区域,它是静态的,在编写代码时就已经确定了

不同于执行上下文,(执行上下文是动态的,执行创建)

举例:

执行上下文时 建房子 时的 打地基

作用域 是 建房子 时的 区域

作用:用来决定代码执行的范围,变量所属的范围

2. 作用域和执行上下文区别

作用域执行上下文
创建时刻函数定义function a() {}函数调用a()
性质静态的,函数定义了,就不会变化动态的
存在时间不会变化调用时创建,调用结束释放

联系:

  • 上下文环境(对象) 是从属于所在的 作用域
  • 全局上下文环境 ==> 全局作用域
  • 函数上下文 ==> 对应的函数作用域

二、作用域链

1. 概念

作用域链:

  • 作用域链 ,是一个数组结构
  • 该结构保存的是 一个个的变量对象

作用域 是人们虚拟出来的,实际上,作用域根本不存在

但是,作用域链是真实存在的

作用:有句话说:找属性去找原型链,找变量去找作用域链

流程:

  1. 先在自身的作用域的变量对象找
  2. 没有,沿着作用域链,去上一个作用域的变量对象找

2. 例子解释

看以下代码,我通过断点的方式,来解释这个概念

/* 断点一 */
var a = 2;    
function fn1() {
  /* 断点二 */
  var b = 3;
  function fn2() {
    /* 断点三 */
    var c = 4;
    console.log(c) // 4
    console.log(b) // 3
    console.log(a) // 2
    console.log(d) // 报错
  }
  fn2()
}

fn1()

首先,通过 debug调试,将代码执行带断点一的地方停下

那么:

  1. 首先创建全局作用域 和 全局变量对象global
  2. global收集了函数fn1,为他创建局部作用域
  3. 这时,在函数fn1建立一个作用域链,里面保存一个变量对象global

在这里插入图片描述

然后,执行到断点二的地方停下:

  1. 首先,在fn1的作用域内,创建一个变量对象Local: fn1
  2. Local:fn1,收集了函数fn2,为他创建局部作用域
  3. 这时,在函数fn2建立一个作用域链,将Local:fn1插入到链的头部
  4. 那么,这时作用域链,就有[ Local:fn1, global ]

在这里插入图片描述

那么,这个由 [[Scopes]]属性存储的变量对象,就是作用域链

3. 笔试题(附解析)

/* 输出什么 */
var x = 10;
function fn() {
  console.log(x)
}
function show(f) {
  var x = 20
  f()  
}
show(fn)

答案:10

解析:

  1. 首先,创建全局作用域和变量对象global
  2. global收集函数fn、show,创建局部作用域,两个的作用域链都只有一个global对象
  3. 执行代码,fn, show创建自身的作用域链,[[scopes]] = [global]
  4. 执行到fn()时,由于要找变量,那么先找自身的作用域的变量对象Local:fn
  5. fn自身没有x变量,找作用域链的上一个变量对象global
  6. globalx变量为 10
  7. 输出 10

4. 练习

console.log(fn)
var fn = function () {
  console.log(fn)
}
fn()
var obj = {
  fn2: function () {
    console.log(fn2)
  }
}
obj.fn2()

答案:

第一道:undefined、 f() {console.log(fn)}

第二道: 报错:fn2 is not function

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值