JavaScript 的执行环境 参考学习:https://blog.csdn.net/zwkkkk1/article/details/79766224#commentBox JS执行顺序-函数声明提升、匿名函数、函数表达式 参考学习:https://www.cnblogs.com/can-i-do/p/8574450.html JavaScript关于作用域、作用域链和闭包的理解: 参考学习:https://blog.csdn.net/whd526/article/details/70990994
声明的顺序是这样的: 1. 找到所有的函数声明,初始化函数体,如有同名的函数则会进行覆盖 2. 查找变量声明,初始化为undefined,如果已经存在同名的变量,就什么也不做直接略过1.脚本执行js引擎都做了什么呢?
语法分析 很简单,就是引擎检查你的代码有没有什么低级的语法错误预编译 简单理解就是在内存中开辟一些空间,存放一些变量与函数解释执行 顾名思义便是执行代码
2.声明式函数 赋值型函数 匿名函数 自执行函数
声明式函数 和 赋值型函数 声明函数与赋值函数的区别在于: 在 JS 的预编译期间,声明式函数会被先提取出来, 然后才按照顺序执行 JS代码。 1 声明式: A(); // 'A ' function A() { console.log('A'); } 2.赋值型: B(); // error, B is not a function var B = function() { console.log('B'); } 3.匿名函数 没有名字的函数就是匿名函数。 function() {} // 匿名函数 4.自执行函数 (function() { console.log(3); })();3.有关代码块script
代码块相互独立,变量和方法共享 代码块内出错依旧继续执行 JS引擎是按代码块顺序执行的(无法预处理)
4.函数
1.都是函数声明(后来居上)
f(); // 我是函数声明2 function f() { console.log('我是函数声明1'); } function f() { console.log('我是函数声明2'); }2.函数声明提前于赋值函数
f(); // 我是函数声明 function f() { console.log('我是函数声明'); } var f = function() { console.log('我是赋值型函数'); }3.函数声明提升优先级大于 变量声明,函数声明覆盖 变量声明
console.log(f); // Function function f() { console.log(1); } var f = 3;例题(声明式函数和赋值性函数):
var getName = function(){ console.log(2); } function getName (){ console.log(1); } getName(); //结果为2=====================================
function getName (){ console.log(1); } var getName = function(){ console.log(2); } getName(); // 结果为2=====================================
getName(); //结果为 1 function getName() { console.log(1); } var getName = function() { console.log(2); }5.执行环境
执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为。每个执行环境都有一个与之关联的变量对象(variableobject,一般简写为VO),环境中定义的所有变量和函数都保存在这个对象中。虽然我们编写的代码无法访问这个对象,但解析器在处理数据时会在后台使用它。
6.预编译(函数执行前)
创建AO对象(Active Object)查找函数形参及函数内变量声明,形参名及变量名作为AO对象的属性,值为undefined实参形参相统一,实参值赋给形参查找函数声明,函数名作为AO对象的属性,值为函数引用7.预编译(脚本代码块script执行前)
查找全局变量声明(包括隐式全局变量声明,省略var声明),变量名作全局对象的属性,值为undefined查找函数声明,函数名作为全局对象的属性,值为函数引用8.变量对象 活动对象 参考学习:http://www.cnblogs.com/hezhi/p/10053025.html https://www.qdfuns.com/article/13446/3510a52e53e9d43b1159f521a5832816.html 变量对象:每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中。 活动对象:在函数执行环境中,VO 是不能直接访问的,则将其活动对象(activation object)作为变量对象。
当一段 JavaScript 代码运行时,解释器(编译器)会创建执行环境,这里会有两个阶段: 创建阶段(编译阶段,当函数被调用,但是开始执行函数内部代码之前) 创建 Scope chain 创建 VO / AO 设置 this 的值 代码执行阶段 设置变量的值、 函数的引用, 然后解释、执行代码对于创建 VO / AO,JavaScript 编译器主要做了下面的事:
根据函数的参数,创建并初始化 arguments对象 扫描函数内部代码,查找函数声明(Function declaration) 对于所有找到的函数声明,将函数名和函数引用存入 VO / AO 中 如果 VO / AO 中已经有同名的函数(变量),那么就进行覆盖 扫描函数内部代码,查找变量声明(Variable declaration) 对于所有找到的变量声明,将变量名存入VO/AO中,并初始化为"undefined" 如果变量名称跟已经声明的形参或函数相同,则变量声明不会干扰已经存在的这类属性===================================== 全局变量对象
var foo = 10; function bar() {} // // 函数声明 (function baz() {}); // 函数表达式 console.log( this.foo == foo, // true window.bar == bar // true ); console.log(baz); // 引用错误,baz没有被定义全局上下文中的变量对象(VO)会有如下属性:
全局变量对象
活动对象:
function foo(x, y) { var z = 30; function bar() {} // 函数声明 (function baz() {}); // 函数表达式 } foo(10, 20);“foo”函数上下文的下一个激活对象(AO)如下图所示:活动对象
