浅谈javascript引擎执行代码的步骤-(2019-2)
平时面试经常会遇到类似下面的这种题,而且千变万化,让人一个头两个。示例这道题算是稍微有点难度的了,这种题考查的是JavaScript引擎执行代码的步骤。
b = 'cba';
function a(a, a){
console.log(a);
console.log(b);
var b = 'abc'; a();
function a(){
console.log(a);
console.log(b);
}
}
a(5,10);
先上理论:
(1)分析脚本的执行过程,也就是全局作用域下的代码。
①创建全局对象GO(window)
②加载脚本代码
③预编译:依此找到var开头的变量声明,把变量加入到全局对象中;找到function开头的函数声明,也放到全局对象中,如果有相同的变量名或函数名,替换之前的;非声明的语句不予理睬;
④解释执行,变量赋值,函数调用
(2)分析每个函数的执行过程
①创建每个函数对象AO(Active Object)
②预编译:创建作用域链;初始化arguments;初始化形参,绑定arguments和形参;找到变量声明加入到AO;找到函数声明加入到AO;
③解释执行
-----------------------------------------------------------------------------------------------------------------------------
具体分析上面的代码:
全局作用域下预编译阶段:
b = 'cba';//忽略,既不是变量声明,也不是函数声明
function a(a, a){//function开头的函数声明,GO加入函数a,函数体忽略
console.log(a);
console.log(b);
var b = 'abc';
a();
function a(){
console.log(a);
console.log(b);
}
}
a(5,10); 全局作用域下解释执行:
b = 'cba';//GO中加入变量b,且赋值为'cba'
function a(a, a){
console.log(a);
console.log(b);
var b = 'abc';
a();
function a(){
console.log(a);
console.log(b);
}
}
a(5,10);//执行函数a,然后生成a的AO 函数a的预编译阶段:
初始化arguments;
初始化形参,两个形参名都为a,后赋的值会替换先赋的值,a先赋值为5,后赋值为10,所以此时变量a为10;
console.log(a);//不是变量声明,忽略
console.log(b);//忽略
var b = 'abc';//是变量声明,将变量b加入到AO,值为undefined
a();//忽略
//函数声明,函数a与形参a同名,替换之前的a=10,此时a为function
function a(){
console.log(a);
console.log(b);
} 函数a解释执行阶段:
console.log(a);//输出function
console.log(b);//输出undefined
var b = 'abc';//变量b赋值'abc'
a();//执行,此处省略分析子函数a的预编译过程
function a(){
console.log(a); //子函数a的AO中没有变量a,向父函数a中寻找,所以输出function
console.log(b); //子函数a的AO中没有变量b,向父函数a中寻找,所有输出'abc'
}
有点乱哈,我写的可能也不是很清楚,不过这个真的很重要,我也是想通过这种方式能让自己加深印象,也希望有需要的人如果看到多少能提供一点帮助。
浅谈javascript引擎执行代码的步骤-(2019-2)的更多相关文章
- 浅谈javascript函数执行过程
javascript函数执行过程: 1. 为函数创建一个执行环境 2. 复制函数的 [[scopes]] 属性中的对象构建起执行环境的作用链域 3. 创建函数活动对象并推入执行环境作用链域的前端 4. ...
- 浅谈 JavaScript new 执行过程及function原理
前言 最近在学习JavaScript语言精粹,感觉写得相当不错.所以这里也算是总结一下.一个方法使用new的方式创建到底是怎样的过程,一个function的声明内部又是怎样执行的呢 另外学的过程中,不 ...
- 浅谈javascript函数节流
浅谈javascript函数节流 什么是函数节流? 函数节流简单的来说就是不想让该函数在很短的时间内连续被调用,比如我们最常见的是窗口缩放的时候,经常会执行一些其他的操作函数,比如发一个ajax请求等 ...
- 浅谈JavaScript中的闭包
浅谈JavaScript中的闭包 在JavaScript中,闭包是指这样一个函数:它有权访问另一个函数作用域中的变量. 创建一个闭包的常用的方式:在一个函数内部创建另一个函数. 比如: functio ...
- 浅谈 JavaScript 编程语言的编码规范
对于熟悉 C/C++ 或 Java 语言的工程师来说,JavaScript 显得灵活,简单易懂,对代码的格式的要求也相对松散.很容易学习,并运用到自己的代码中.也正因为这样,JavaScript 的编 ...
- 浅谈javascript的原型及原型链
浅谈javascript的原型及原型链 这里,我们列出原型的几个概念,如下: prototype属性 [[prototype]] __proto__ prototype属性 只要创建了一个函数,就会为 ...
- [转载]浅谈JavaScript函数重载
原文地址:浅谈JavaScript函数重载 作者:ChessZhang 上个星期四下午,接到了网易的视频面试(前端实习生第二轮技术面试).面了一个多小时,自我感觉面试得很糟糕的,因为问到的很多问题都 ...
- javascript引擎执行的过程的理解--执行阶段
一.概述 同步更新sau交流学习社区(nodeJSBlog):javascript引擎执行的过程的理解--执行阶段 js引擎执行过程主要分为三个阶段,分别是语法分析,预编译和执行阶段,上篇文章我们介绍 ...
- 浅谈JavaScript中的正则表达式(适用初学者观看)
浅谈JavaScript中的正则表达式 1.什么是正则表达式(RegExp)? 官方定义: 正则表达式是一种特殊的字符串模式,用于匹配一组字符串,就好比用模具做产品,而正则就是这个模具,定义一种规则去 ...
随机推荐
- Alpine Linux 安装 lxml Pillow 失败
lixm 需要编译安装,因此需要先安装gcc g++ RUN apk add --update --no-cache g++ gcc libxslt-dev python3-dev openssl-d ...
- 记一次收集APP native崩溃信息
最近在学习 极客时间Android开发高手课 老师推荐了Breakpad开源库来采集native 的crash1.为什么要使用Google Breakpad? 我们在开发过程中,Android JNI ...
- Kafka常见错误整理(不断更新中)
1.UnknownTopicOrPartitionException org.apache.kafka.common.errors.UnknownTopicOrPartitionException: ...
- JXL工具包对Excle文件操作
1.简介: XL - JXL(Java Excel API)是一个用来动态读写 Excel 文件的开源框架,利用它可以 在任何支持 Java 的操作系统上动态读写 Excel 文件. 2.开发步骤 1 ...
- WCF全双工通信实例分享(wsDualHttpBinding、netTcpBinding两种实现方式)
最近在研究WCF通信,如果没有接触过的可以看我的前一篇文章:https://www.cnblogs.com/xiaomengshan/p/11159266.html 主要讲的最基础的basicHttp ...
- JS基础语法---函数练习part1---5个练习
练习1:求两个数字的和:获取任意的两个数字的和 function getSum(x, y) { return x + y; } console.log(getSum(10, 20)); 练习2:求1- ...
- H5 移动端 键盘遮挡焦点元素解决方案
前言 最近在做 webapp,遇到了很多移动端兼容的问题,其中一个问题就是:输入框触发 focus 后,键盘弹出,然后遮住了输入框. 然后在Android和IOS上,这个问题的表现形式不一样,而原生键 ...
- LFI (local file inclusion vulnerability)本地文件包含
代码实例: <?php $file = $_GET['file']; if(isset($file)) { include("pages/$file"); } else { ...
- 【转载】Gradle for Android 第六篇( 测试)
由于现阶段Android开发趋于敏捷开发,再加上国内大大小小的互联网公司都在做app,导致很多这会是一个系列,所以如果你看完这篇文章,请看下列文章: 开发人员对单元测试没有基本的概念,但是本篇博文不会 ...
- C语言、指针(一)
指针(一) “带*类型” 的特征探测:宽度 “带*类型” 的特征探测:声明 “带*类型” 的特征探测:赋值 “带*类型” 的特征探测:++ -- “带*类型” 的特征探测:加上/减去 一个整数 “带* ...