面试再探讨:浏览器中js的执行与机制

前言

上回我们深入了解了作用域、作用域链,那么今天我们再次深入探讨一下浏览器中js的执行与机制的底层原理,聊聊调用栈作用域链这一全过程,全局执行上下文函数执行上下文eval执行上下文,这个创建、删除过程又是通过一个什么数据结构完成的呢?

面试题引入

在此之前先给各位安利一款百度最近刚刚开源的插件,vs中或者其他idea类全家桶都能够安装,comate.baidu.com/index.html?... ,你也可以之前通过vs插件搜索baiducomate,真的很智能,你们可以去试试。

ini 复制代码
function bar(params) {
    console.log(myName);
}

function foo(params) {
    var myName = 'Tom'
    bar();
}

var myName = 'Jerry';

foo();

题目很简单,但是需要你真正理解底层的执行过程

变量提升(发生在编译阶段)

在 JavaScript 中,变量提升是指在代码执行之前,变量和函数声明会被提升到当前作用域的顶部。 这意味着即使在声明之前使用变量,也不会导致错误,但此时变量的值是 undefined。 需要注意的是,只有声明会被提升,赋值操作不会被提升。

ini 复制代码
console.log(x); // 输出 undefined 
var x = 5;

那么这个代码事实上长这样

ini 复制代码
var x
console.log(x); 
x = 5;

包含函数的变量提升

javascript 复制代码
console.log(myFunction); // 输出函数定义

function myFunction() {
  console.log("函数被调用");
}

在js引擎的眼中的执行上下文创建过程

之前我们谈过GO(全局作用域对象)、AO对象,那么其实每一个执行上下文中都有一个变量环境和一个词法环境,变量环境中放var的声明变量和函数声明,词法环境中放let和const声明的变量。接下来回到这个面试题引入部分

ini 复制代码
function bar(params) {
    console.log(myName);
}

function foo(params) {
    var myName = 'Tom'
    bar();
}

var myName = 'Jerry';

foo();

分析过程

这些创建的GO\AO对象都存放在哪里呢?

  • 栈结构: 特殊的数组,先进后出
  • 调用栈: js引擎用来追踪函数调用关系的
  • 栈溢出: 调用栈超出内存限制 代码从上往下执行,在全局中首先创建GO对象,也就是全局执行上下文,存放在栈中,放入栈底,全局上下文中有变量环境与词法环境,代码从上往下执行就会发现声明了bar函数和foo函数以及myName变量。图中(全局可执行对象打错了,应该是全局执行上下文!)

紧接着就执行代码,调用foo函数,既然要调用foo函数,首先就需要对foo函数进行预编译,创建AO对象,放入栈中,变量声明首先值为undefined,然后赋值为Tom

紧接着执行调用bar函数,此时需要对bar函数进行预编译,创建AO对象

打印myName,那么在这里就发现了bar执行上下文中没有myName,那么接下来这个属性去哪里找呢?我们都知道,执行上下文中会从词法环境开始找,然后再找变量环境,如果都没有呢?是顺着栈顶向下找吗?答案是否定的。事实上每一个执行上下文中,都存有一个outer属性,这个outer属性的规则是:我的词法作用域(在函数定义时所在的作用域)在哪里,我就指向哪里。那么在bar中,bar的词法作用域存在于全局执行上下文中,那么这个outer就指向全局执行上下文,在自己的bar执行上下文对象中没有找到myName属性,就去全局中找,全局中myName属性值为Jerry,前面的图忘记加上了,在调用foo之前,已经执行过对Myname属性赋值的语句了,这也是一个执行代码的过程

接下来bar函数执行完毕,需要对bar的执行上下文进行释放,弹栈,然后foo执行完毕,进行弹栈,在这我们能够理解,如果不弹栈,见到一个我们就需要创建一个执行上下文对象,长此以往,就会造成栈溢出

小结

本次内容虽然很简单,但是极易出错,知识点都是代码的底层逻辑,理解透彻以后才能在面试时对答如流从容面对。再次多提一下,在执行上下文中的查找过程,是从词法环境查找然后再往变量环境中查找,每一个环境又是一个小的栈结构,也是从栈顶开始向栈底查找,如图所示:

相关推荐
passerby60618 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了8 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅8 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅8 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅8 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment9 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅9 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊9 小时前
jwt介绍
前端
爱敲代码的小鱼9 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax
Cobyte9 小时前
AI全栈实战:使用 Python+LangChain+Vue3 构建一个 LLM 聊天应用
前端·后端·aigc