JavaScript篇:解密JS执行上下文:代码到底是怎么被执行的?

大家好,我是江城开朗的豌豆,一名拥有6年以上前端开发经验的工程师。我精通HTML、CSS、JavaScript等基础前端技术,并深入掌握Vue、React、Uniapp、Flutter等主流框架,能够高效解决各类前端开发问题。在我的技术栈中,除了常见的前端开发技术,我还擅长3D开发,熟练使用Three.js进行3D图形绘制,并在虚拟现实与数字孪生技术上积累了丰富的经验,特别是在虚幻引擎开发方面,有着深入的理解和实践。

我一直认为技术的不断探索和实践是进步的源泉,近年来,我深入研究大数据算法的应用与发展,尤其在数据可视化和交互体验方面,取得了显著的成果。我也注重与团队的合作,能够有效地推动项目的进展和优化开发流程。现在,我担任全栈工程师,拥有CSDN博客专家认证及阿里云专家博主称号,希望通过分享我的技术心得与经验,帮助更多人提升自己的技术水平,成为更优秀的开发者。

技术qq交流群:906392632

大家好,我是小杨,一个和JS相爱相杀6年的前端工程师。今天我要带大家揭开JavaScript代码执行的神秘面纱,保证让你看完后恍然大悟:"原来我的代码是这样跑的!"

一、执行上下文:代码的"舞台"

想象一下,JS引擎就像个剧场,每次函数调用就像一场新的演出。而执行上下文就是这个演出的"舞台",决定了哪些"演员"(变量和函数)可以上场。

先看个简单例子:

javascript 复制代码
function sayHello() {
    let me = '小杨';
    console.log(`大家好,我是${me}`);
}
sayHello();

当调用sayHello()时,JS就会创建一个新的执行上下文。

二、执行上下文的"人生三阶段"

每个执行上下文都会经历三个阶段:

  1. 创建阶段:准备舞台

    • 创建变量对象(VO)
    • 建立作用域链
    • 确定this指向
  2. 执行阶段:正式演出

    • 变量赋值
    • 函数调用
    • 执行代码
  3. 销毁阶段:演出结束

    • 出栈等待垃圾回收

三、变量提升的真相

来看个经典例子:

javascript 复制代码
console.log(me); // undefined
var me = '小杨';
console.log(me); // '小杨'

为什么不会报错?因为在创建阶段,变量声明会被提升,但赋值不会。

小杨踩坑记

javascript 复制代码
function test() {
    console.log(me); // undefined
    if(false) {
        var me = '小杨';
    }
}
test();

即使if条件为false,变量声明依然会被提升!

四、作用域链:变量的"寻亲记"

javascript 复制代码
let name = '全局小杨';

function outer() {
    let name = '外层小杨';
    
    function inner() {
        console.log(name); // '外层小杨'
    }
    inner();
}
outer();

JS会沿着作用域链一层层往上找变量,就像寻亲一样。

五、this指向:最难捉摸的"演员"

this的指向总让人头大,记住几个规则:

  1. 普通函数调用:this指向window(严格模式undefined)
  2. 方法调用:this指向调用对象
  3. new调用:this指向新创建的对象
javascript 复制代码
let obj = {
    me: '小杨',
    say: function() {
        console.log(this.me);
    }
};

obj.say(); // '小杨'
let fn = obj.say;
fn(); // undefined (this指向window)

六、闭包:执行上下文的"遗产"

javascript 复制代码
function createCounter() {
    let count = 0;
    return function() {
        count++;
        console.log(count);
    };
}

let counter = createCounter();
counter(); // 1
counter(); // 2

即使createCounter的执行上下文已经销毁,内部函数依然能访问count变量,这就是闭包的魔力。

七、实战应用:避免常见坑

  1. 避免变量污染
javascript 复制代码
// 错误做法
for(var i=0; i<5; i++) {
    setTimeout(() => {
        console.log(i); // 全是5
    }, 100);
}

// 正确做法
for(let i=0; i<5; i++) {
    setTimeout(() => {
        console.log(i); // 0,1,2,3,4
    }, 100);
}
  1. 合理使用闭包
javascript 复制代码
// 缓存计算结果
function createCache() {
    let cache = {};
    return function(key, value) {
        if(value !== undefined) {
            cache[key] = value;
        }
        return cache[key];
    }
}

八、总结

  • 执行上下文是JS代码执行的环境
  • 变量提升和作用域链是理解JS的关键
  • this指向需要根据调用方式判断
  • 闭包可以让函数"继承"执行上下文的变量

最后留个思考题:

javascript 复制代码
let obj = {
    me: '小杨',
    say: () => {
        console.log(this.me);
    }
};
obj.say(); // 输出什么?为什么?

欢迎在评论区讨论你的答案!下期我会详细讲解箭头函数的this指向问题。

相关推荐
zwjapple1 小时前
docker-compose一键部署全栈项目。springboot后端,react前端
前端·spring boot·docker
像风一样自由20203 小时前
HTML与JavaScript:构建动态交互式Web页面的基石
前端·javascript·html
aiprtem4 小时前
基于Flutter的web登录设计
前端·flutter
浪裡遊4 小时前
React Hooks全面解析:从基础到高级的实用指南
开发语言·前端·javascript·react.js·node.js·ecmascript·php
why技术4 小时前
Stack Overflow,轰然倒下!
前端·人工智能·后端
GISer_Jing4 小时前
0704-0706上海,又聚上了
前端·新浪微博
止观止5 小时前
深入探索 pnpm:高效磁盘利用与灵活的包管理解决方案
前端·pnpm·前端工程化·包管理器
whale fall5 小时前
npm install安装的node_modules是什么
前端·npm·node.js
烛阴5 小时前
简单入门Python装饰器
前端·python
袁煦丞6 小时前
数据库设计神器DrawDB:cpolar内网穿透实验室第595个成功挑战
前端·程序员·远程工作