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指向问题。

相关推荐
Mintopia几秒前
3D Quickhull 算法:用可见性与冲突图搭建空间凸壳
前端·javascript·计算机图形学
Mintopia1 分钟前
Three.js 三维数据交互与高并发优化:从点云到地图的底层修炼
前端·javascript·three.js
陌小路7 分钟前
5天 Vibe Coding 出一个在线音乐分享空间应用是什么体验
前端·aigc·vibecoding
成长ing1213815 分钟前
cocos creator 3.x shader 流光
前端·cocos creator
Alo36523 分钟前
antd 组件部分API使用方法
前端
BillKu26 分钟前
Vue3数组去重方法总结
前端·javascript·vue.js
GDAL28 分钟前
Object.freeze() 深度解析:不可变性的实现与实战指南
javascript·freeze
江城开朗的豌豆1 小时前
Vue+JSX真香现场:告别模板语法,解锁新姿势!
前端·javascript·vue.js
这里有鱼汤1 小时前
首个支持A股的AI多智能体金融系统,来了
前端·python
袁煦丞1 小时前
5分钟搭建高颜值后台!SoybeanAdmin:cpolar内网穿透实验室第648个成功挑战
前端·程序员·远程工作