js执行上下文(由浅入深)
每一个函数都有自己的执行上下文EC(执行环境 execution context),并且每个执行上下文中都有它自己的变量对象VO(Variable object),用于存储执行上下文中的变量 、函数声明 、函数参数,这解释了js如何找到我们定义的函数和变量。并且函数是js中唯一一个能创建出作用域的,注意:for,if()else()不能创建作用域。我们通过以下几个例子说明为什么函数和变量的声明会被前置,为什么匿名函数表达式的不可以在外面调用。
var a = 18;
f1();
function f1(){
var b=9;
console.log(a); //undefined
console.log(b); //
var a = '123';
}
因为在f1中,在此函数还未执行时变量a,b会被提前声明,也就是说可以理解为下面的代码
var a = 18;
f1();
function f1(){
var b;
var a;
b = 9;
console.log(a);
console.log(b);
a = '123';
}
如果想进一步理解内部的运行机制,可以用如下方法:
在此案例中,f1函数的作用域链有两个对象,一个是全局变量对象,一个是f1变量对象。
VO (globalContext) = {
a: 18,
f1: <ref to function>
}
1.变量初始化阶段
VO (f1 functionContext) = {
a: undefined,
b: undefined
}
2.代码执行阶段
VO (f1 functionContext) = {
a: undefined,
b: 9
}
再来两个js经典题
function fn(a){
console.log(a); //function(){}
var a = 2;
function a(){};
console.log(a); //
}
fn(1);
我们知道,在运行fn之前,变量和function都会提前声明,但是function会覆盖变量(在不赋值的前提下),


通过以上案例,我们可以总结如下规律:
VO按照如下顺序填充:
1. 函数参数 (若未传入,初始化该参数值为undefined)
2. 函数声明 (若发生命名冲突,会覆盖)
3. 变量声明 (初始化变量值为undefined,若发生命名冲突,会忽略。)
注意:变量初始化(被声明)和变量根本不在一个变量对象里是有区别的,如果用console打印前者会显示undefined,而后者会报一个"ReferenceError: gg is not defined"。
比如

第一个只有一个全局上下文
VO (globalContext) = {
fn: <ref to function>
}
因为没有执行fn,所以里面的变量读取不到,第二个通过声明被前置,打印undefined.(只有var的变量才能被前置)
为了让大家充分了解执行上下文,再来一个例子。
function test(a,b){
var c = 10;
function d(){}
var e = function _e(){};
(function x(){});
b = 20;
}
test(10);
第一阶段——变量初始化阶段如下 第二阶段——代码执行阶段

提示:因为此函数中有形参b,所以在变量初始化阶段会b:undefined,如果没有形参b,会报错 b is not defined。
最后来一个压轴的
alert(a); //undefined
alert(b); //undefined
alert(x); //function x(){}
var x = 10;
alert(x); // 10
x = 20;
function x(){}
alert(x); // 20
if (true) {
var a = 1;
} else {
var b = true;
}
alert(a); //1
alert(b); //undefined
首先声明一点,js是没有块级作用域的,所以if{}else{}里面的变量即使不执行,他们的声明也会前置,所以第一个和第二个alert为undefined,对于第三个alert,因为先是x这个变量前置,然后x又变成了function,前面说过了,函数声明如果发生冲突会覆盖变量声明(可以理解为function的优先级更高),所以第三个弹出function,第四个赋值为10,第五个x=20覆盖x=10,第六个因为执行了if,所以给a赋值弹出1,最后一个还是undefined。
js执行上下文(由浅入深)的更多相关文章
- JS执行上下文(执行环境)详细图解
JS执行上下文(执行环境)详细图解 先随便放张图 我们在JS学习初期或者面试的时候常常会遇到考核变量提升的思考题.比如先来一个简单一点的. console.log(a); // 这里会打印出什么? v ...
- 一篇文章看懂JS执行上下文
壹 ❀ 引 我们都知道,JS代码的执行顺序总是与代码先后顺序有所差异,当先抛开异步问题你会发现就算是同步代码,它的执行也与你的预期不一致,比如: function f1() { console.lo ...
- 深入理解js——执行上下文
什么是"执行上下文"?暂且不下定义,先看一段代码: 第一句报错,a未定义,很正常.第二句.第三句输出都是undefined,说明浏览器在执行console.log(a)时,已经知道 ...
- js执行上下文
js在执行是会有一个“准备工作”: 主要内容有 1.变量.函数表达式——>变量声明,默认赋值为undefined: 2.this——>赋值: 3.函数声明——>赋值: 这三种数据的准 ...
- 前端高质量知识(二)-JS执行上下文(执行环境)详细图解Script
先随便放张图 我们在JS学习初期或者面试的时候常常会遇到考核变量提升的思考题.比如先来一个简单一点的. console.log(a); // 这里会打印出什么? var a = 20; PS: 变量提 ...
- js执行上下文栈和变量对象
JavaScript执行上下文栈和变量对象 JS是单线程的语言,执行顺序肯定是顺序执行,但是JS 引擎并不是一行一行地分析和执行程序,而是一段一段地分析执行,会先进行编译阶段然后才是执行阶段. 例子一 ...
- 原型模式故事链(4)--JS执行上下文、变量提升、函数声明
上一章:JS的数据类型 传送门:https://segmentfault.com/a/11... 好!话不多少,我们就开始吧.对变量提升和函数声明的理解,能让你更清楚容易的理解,为什么你的程序报错了~ ...
- js执行上下文与执行上下文栈
一.什么是执行上下文 简单说就是代码运行时的执行环境,必须是在函数调用的时候才会产生,如果不调用就不会产生这个执行上下文.在这个环境中,所有变量会被事先提出来(变量提升),有的直接赋值,有的为默认值 ...
- JS 执行上下文的一次理解
执行上下文 执行上下文概念 当代码运行时,会产生一个对应的执行环境,在这个环境中,变量会被事先提出来(变量提升),代码从上往下开始执行,就叫做执行上下文. 注:在定义变量是未直接赋值,使用默认值 un ...
随机推荐
- Android小项目练习之一 项目简介
------- 源自梦想.永远是你IT事业的好友.只是勇敢地说出我学到! ---------- 按惯例,写在前面的:可能在学习Android的过程中,大家会和我一样,学习过大量的基础知识,很多的知识点 ...
- jquery查找父元素、子元素(个人经验总结)
使用js或者jquery查找父元素.子元素经常遇到.可是用起来总容易混淆,这里统一总结了一下,以后用起来相信会方便好多 这里jquery向上查找父元素 用到的方法:closest() parents( ...
- hdu 4745 动态规划
思路:特水的一个最长回文子序列动态规划.比赛时硬卡第一题,49WA后终于AC,可惜没时间做这题,结果成绩也就可想而知了.兔子跳一样权值的石头,并且一个正跳,一个反跳,这不就是个回文子序列吗?????! ...
- c# 匿名对象增加动态属性
在开发过程中碰到了一个需求,需要动态创建对象及其动态属性.在尝试几种方法后,最后完成了需求,记录下过程,给园友参考下 1.动态创建对象一:匿名对象 ",Birthday =DateTime. ...
- 如何提高手机APP的用户体验?
详细内容请点击 随着移动互联网如日中天,如火如荼的时候,手机APP开发日益高涨了起来,关于手机APP的用户体验,也是一个老话长谈的话题.从事这行业也很久了,以下是我个人在工作中的一些关于APP的用户体 ...
- 【CSS3】---练习制作导航菜单
练习题 根据所学知识,使用CSS3实现下图的导航菜单效果 任务 1.制作导航圆角 提示:使用border-radius实现圆角 2.制作导航立体风格 提示:使用box-shadow实现立体风格 3.制 ...
- Java开发从零开始填坑
开始学习Java,感觉较.NET知识更零碎一些,所以开个帖子把自己踩过的坑记录下来,都是边边角角网上不容易找到的东西. 1.java命令格式:>cd %parent-of-pakadgePath ...
- java模拟有验证码的Http登陆
所需资源下载链接(资源免费,重在分享) Tesseract:http://download.csdn.net/detail/chenyangqi/9190667 jai_imageio-1.1-alp ...
- php学习笔记6--php中的文件包含 include,require,include_once,require_once
php中的文件包含 include,require,include_once,require_once 文件包含:是指将一个文件的内容包含进另外一个文件,有利于代码的复用等.php中文件包含指令有4个 ...
- Android处理Bitmap使其能够不失真等比缩放裁剪后显示在ImageView上
Android开发过程中,我们有时需要动态得显示一些图片,并且这些图片的大小差距会十分大,如果需求并不是需要图片完整显示,但是需要不失真,并且要图片中间部分的情况下,我们需要做一系列处理,因为这个时候 ...