参考

https://www.jianshu.com/p/3b5f0cb59344

https://jingyan.baidu.com/article/4f34706e18745be386b56d46.html

https://www.2cto.com/kf/201401/273825.html

https://www.cnblogs.com/zqzjs/p/5497955.html

运行机制

JavaScript代码的执行是由浏览器中的JavaScript解析器来执行的。JavaScript解析器执行JavaScript代码的时候,分为两个过程:预解析过程和代码执行过程。即先解析(例如先进行变量、函数的声明提升),后运行。

JavaScript 运行分为两个阶段:

- 预解析
- 全局预解析(所有变量和函数声明都会提前;同名的函数和变量函数的优先级高)
- 函数内部预解析(所有的变量、函数和形参都会参与预解析)
- 函数
- 形参
- 普通变量
- 执行 先预解析全局作用域,然后执行全局作用域中的代码, 在执行全局代码的过程中遇到函数调用就会先进行函数预解析,然后再执行函数内代码。

1. 预解释/预处理,变量提升(Hoisting)

预解析过程:

  1. 把变量的声明提升到当前作用域的最前面,只会提升声明,不会提升赋值。
  2. 把声明式函数(JS有赋值式函数/函数表达式var f = function(){},这个不能被提升)的声明提升到当前作用域的最前面,只会提升声明,不会提升调用。
  3. 先提升var,在提升function

打印2次2。因为foo()提升到当前作用域的顶部。

function foo() {
console.log('1');
}; foo(); function foo() {
console.log('2');
}; foo();

JS解释器逐个块(一个<script>就是一个块)解释。先到第一个<script>,f1提升到全局作用域(打印哈哈)。到第二个<script>,最新的function f1的声明提升到全局作用域,当然执行最新的一个声明(打印嘎嘎)。

    <script>
function f1() {
console.log("哈哈");
} f1();
</script>
<script>
f1(); function f1() {
console.log("嘎嘎");
}
</script> <script>
f1();
</script>

// 1、-----------------------------------
var num = 10;
fun();
function fun() {
console.log(num);
var num = 20;
}
//2、-----------------------------------
var a = 18;
f1();
function f1() {
var b = 9;
console.log(a);
console.log(b);
var a = '123';
}
// 3、-----------------------------------
f1();
console.log(c);
console.log(b);
console.log(a);
function f1() {
var a = b = c = 9;
console.log(a);
console.log(b);
console.log(c);
}

2. 作用域

在ES5之前JS没有块级作用,有函数作用域。用函数作用域可以避免多个<script>的全局变量污染。先可以认为JS一般没有块级作用域,有函数作用域。

块级作用域: "{}内部声明的变量只能够在{}内部访问到,在{}外部无法访问到其内部声明的变量"

3. 作用域链

当我们在局部作用域中,访问一个变量时,系统首先会在当前作用域中寻找变量var的声明语句,如找到则直接使用。反之,则继续向上一级作用域中寻找var的声明语句,如找到则直接使用,反之,继续向上一级作用域中去寻找…直到全局作用域

例子,尝试注释掉每个f的num

    <script>

        var num = 10;

        function f1() {
var num = 20; function f2() {
var num = 30; function f3() {
var num = 50;
console.log(num);
} f3();
} f2();
} f1();
</script>



4. 隐式全局变量

在function里,用var定义的变量是局部变量;不用var定义的变量为隐式全局变量

        function f1() {
var a;//局部变量
a = 9;
//隐式全局变量
b = 9;
c = 9;
console.log(a);//9
console.log(b);//9
console.log(c);//9
} f1();
console.log(c);// 9
console.log(b);// 9
console.log(a);//报错

JavaScript - 运行机制,作用域,作用域链(Scope chain)的更多相关文章

  1. Javascript 运行上下文和作用域链

    一.作用域Scope和上下文Context 在javascript中,作用域scope和上下文context是两个不同的概念.每个函数调用都会伴随着scope和context,从本质上来说,scope ...

  2. 深入理解JavaScript运行机制

    深入理解JavaScript运行机制 前言 本文是写作在给团队新人培训之际,所以其实本文的受众是对JavaScript的运行机制不了解或了解起来有困难的小伙伴.也就是说,其实真正的原理和本文阐述的并不 ...

  3. javascript运行机制

    太久没更新博客了,Javascript运行机制 Record it 1.代码块 JavaScript中的代码块是指由<script>标签分割的代码段.例如: <script type ...

  4. 从setTimeout谈JavaScript运行机制

    从setTimeout说起 众所周知,JavaScript是单线程的编程,什么是单线程,就是说同一时间JavaScript只能执行一段代码,如果这段代码要执行很长时间,那么之后的代码只能尽情地等待它执 ...

  5. JavaScript运行机制详解

    JavaScript运行机制详解   var test = function(){ alert("test"); } var test2 = function(){ alert(& ...

  6. 深入浅出JavaScript运行机制

    一.引子 本文介绍JavaScript运行机制,这一部分比较抽象,我们先从一道面试题入手: console.log(1); setTimeout(function(){ console.log(3); ...

  7. javascript 运行机制 事件循环 浏览器缓存 (慕课网 前段跳槽面试必备 4-1,4-2,4-3)

    4-1 渲染机制:-1-,什么是DOCTYPE及其作用?DTD(document type definition,文档类型定义)是一系列的语法规则,用来定义XML或(X)HTML的文件类型,浏览器会使 ...

  8. JavaScript运行机制与setTimeout

    前段时间,老板交给了我一个任务:通过setTimeout来延后网站某些复杂资源的请求.正好借此机会,将JavaScript运行机制和setTimeout重新认真思考一遍,并将我对它们的理解整理如下. ...

  9. Javascript 运行机制

    先看一下下面这段js代码: console.log('1'); setTimeout(function(){ console.log('2'); },0); console.log('3'); 请问打 ...

随机推荐

  1. 虚拟机安装的ubuntu不能联网解决

    安装双系统从没遇到的问题,再虚拟机上遇到了不能联网的问题: 下面给出我的解决方法(win10系统.ubuntu 16.04) 我的电脑-管理-设备管理器 看是否虚拟机的虚拟网卡在: 在去设置-控制面板 ...

  2. element-ui里el-form的lable颜色怎么修改?

    就是把style改写成全局的,不要scoped(注意class,id的唯一,不要影响了整体布局) 链接:https://segmentfault.com/q/1010000017251094

  3. [GameOfMir说明] 从文件中随机取文本

    功能: 从文件中随机取文本.格式: GETRANDOMLINETEXT 文件 字符串变量 ;==========================================;示例脚本[@Main] ...

  4. 将项目打成war包并用tomcat部署的方法,步骤及注意点

    部署的遇到第一个问题,就是tomcat和jdk的环境问题: 首先 理解为啥要关注这二者的环境呢?他们还是有关系的–tomcat 作为比较流行的java Web服务器也是用java来实现的一个比较大的软 ...

  5. Bugku-CTF加密篇之这不是md5(666c61677b616537333538376261353662616566357d)

    这不是md5 666c61677b616537333538376261353662616566357d  

  6. 【代码学习】PYTHON 深拷贝和浅拷贝

    1.浅拷贝是对一个对象的顶层拷贝 就是拷贝了引用,并没有拷贝内容 2.深拷贝引用了内容 import copy a = [1,2,3] b = copy.copy(a) c = copy.deepco ...

  7. workflow1

    var workflowDef = { start:{ fn:"begin", //对应处理方法可以在内部定义,也可以在外部定义 next:["task1",& ...

  8. python opencv:保存图像

  9. Linux 笔记:虚拟控制台

    登录后按Alt+F2键这时又可以看到"login:"提示符,这个就是第二个虚拟控制台. 一般新安装的Linux有四个虚拟控制台,可以用Alt+F1~Alt+F4来访问. 虚拟控制台 ...

  10. 【代码学习】PYTHON字符串的常见操作

    一.字符串运算符 下表实例变量 a 值为字符串 "Hello",b 变量值为 "Python": 操作符 描述 实例 + 字符串连接 >>>a ...