块级作用域竟是我自己?JS代码中的打工人
ZZZ复盘学习JS基础,重新认识知识,总结掌握知识,炼化知识,输出知识。这是一篇学习反思,用自己的逻辑把知识体系搭建,用自己的话总结输出。
我将从“打工人”视角来分享我眼中作用域的职场金字塔
复盘变量
变量的概念
在JS中,变量是用于存储数据的「容器」我们通过关键字声明变量,不同关键字对应不同的作用域规则和特性。
JS 中声明变量有三种方式: var 、 let 、 const (其中 let 和 const 是 ES6 新增的语法,解决了 var 的诸多历史问题。)
变量声明代码示例
// var 声明变量
var nameVar = "张三"
// let 声明变量
let nameLet = "李四"
// const 声明常量(必须初始化,不可修改)
const nameConst = "王五"
console.log(nameVar, nameLet, nameConst)
//运行结果 张三 李四 王五
我的金字塔理解
变量就是金字塔里每个人手里的资源:
- 老板(全局)、经理(函数)、员工(块级)都可以声明自己的变量
- 不同声明方式,决定了这个资源「能不能被别人看到、能不能修改」
复盘作用域,作用域链
作用域的概念
作⽤域定义了如何查找变量的位置,即确定当前执⾏上下⽂中变量和其他资源的作⽤范围。
作用域有三类
1. 全局作用域:在代码的任何位置都可访问,是最顶层的作用。
2. 函数作用域:仅在当前函数内部可访问,外部无法直接调用。
3. 块级作用域(es6后引入):由 {} (if、for、代码块等)包裹形成,仅 let / const 声明的变量受其限制。
代码示例
// 1. 全局作用域
let a = 100;
function fn() {
// 2. 函数作用域
let b = 200;
if (true) {
// 3. 块级作用域
let c = 300;
// 里面能访问外面所有
console.log(a); // 100
console.log(b); // 200
console.log(c); // 300
}
// 函数里能访问全局、自己,但不能访问块里的 c
console.log(a); // 100
console.log(b); // 200
// console.log(c); // 报错:c is not defined
}
fn();
// 全局只能访问全局 a,不能访问函数 b、块 c
console.log(a); // 100
console.log(b); // 报错:b is not defined
console.log(c); // 报错:c is not defined
我的金字塔抽象理解
我把JS作用域完全对应成职场金字塔生态:
- 全局作用域 = 公司大老板:权限最高,资源(全局变量)全公司都能调用
- 函数作用域 = 部门经理:权限次之,仅管理自己部门的资源(函数变量)
- 块级作用域 = 普通打工人:权限最低,只有自己工位的资源(块级变量)
- 另外如果在自己的工位(内部作用域)上直接赋值但是没有声明,系统就默认把它放到公司(全局作用域)里面了
function fn() {
// 未声明直接赋值 → 自动成为全局变量
a = 100;
console.log(a); // 100(函数内可访问)
}
fn();
// 全局作用域可直接访问
console.log(a); // 100
核心规则只有两条:
1. 下层可以逐层向上查找资源:打工人能找经理、经理能找老板,最终能访问到顶层全局变量
2. 上层绝对不能向下访问私有资源:老板不能看打工人的私有变量,经理也不能越权访问其他部门的资源
作用域链的概念
当代码在某个作用域中访问变量时,JS引擎会从当前作用域开始,沿作用域链向上逐层查找,直到找到该变量或到达全局作用域;若始终未找到,则抛出 ReferenceError 错误,这条查找链路就是作用域链。 (作用域链的本质是作用域的层级嵌套关系,它保证了变量的隔离性与可访问性)
作用域链代码
// 全局作用域(金字塔顶层:老板)
let a = 10;
function outer() {
// 函数作用域(金字塔中层:经理)
let b = 20;
if (true) {
// 块级作用域(金字塔底层:打工人)
let c = 30;
// 沿作用域链向上查找:块级 → 函数 → 全局
console.log(c); // 30
console.log(b); // 20
console.log(a); // 10
// console.log(d); // 报错:d is not defined(全局也找不到)
}
}
outer();
我的金字塔抽象理解
作用域链就是打工人的「向上汇报链路」: 打工人( inner )找不到资源,先问直属经理( outer ),经理找不到再问大老板(全局),一路向上直到找到为止; 但永远不会出现老板向下问员工要私有资源的情况,完美对应作用域链「单向向上查找」的核心特性。
复盘变量提升
变量提升的概念
JS执行代码前,会先扫描当前作用域内所有 var 声明,把声明提升到作用域最顶部,但赋值不会提升。 let / const 不会这样提升(有暂时性死区)。
1,基础变量提升代码
console.log(a); // undefined
var a = 10;
console.log(b); // 报错(let 没有变量提升)
let b = 20;
2,函数声明优先于 var 声明
函数整体提升 > var 变量提升 同一个名字,函数会覆盖 var。
console.log(num); // [Function: num](函数优先)
var num = 100;
function num() {}
3, 变量提升只发生在自己的作用域
提升不会跨作用域,全局是全局,函数是函数,互不干扰。
console.log(a); // undefined(全局提升)
var a = 10;
function fn() {
console.log(b); // undefined(只在函数内提升)
var b = 20;
}
fn();
console.log(b); // 报错:b is not defined(全局没有 b)
我的金字塔抽象理解
- 变量提升就像提前报到: var 会提前在自己部门(作用域)报备名字,但不分配工作(不赋值)。
- 函数提升比变量更高: 相当于领导优先报到,同一个名字,领导排在前面。
- 提升只在自己部门有效: 全局(老板)、函数(部门)各提各的,不会跨部门提升。
本篇是我复习 JS 基础的学习记录,把作用域相关的知识点用自己的逻辑梳理了一遍.很多概念一开始觉得很高级,但用这种方式去类比,就变得很好理解,毕竟不是专业总结,只是把自己学的知识和想法进一步炼化,让自己能够真正更好的化为己用。
如果有理解不对的地方,欢迎大家指正,一起学习进步