js完成解释执行分为三个步骤:
1.语法分析;2.预编译(全局预编译、函数预编译);3.执行语句。
函数调用时 怎么运行代码的?
1.分析代码是否正确 符号 词法分析
var var=20;
var 01js=100
var a;
var a,
2.隐式操作 ==> 预编译:函数调用了以后 在运行代码之前
2.1函数每次调用都会生成一个对象:执行期上下文对象
2.2.给AO对象添加成员:函数内部的局部变量和形参变量 名 作为AO对象的属性名
AO:{a:undefined}
ao.a=undefined
ao.a=undefined//形参和局部变量一样的时候 不影响
2.3.把传入的实参赋值给AO对象的属性
AO:{a:100}
2.4.局部函数声明,赋值 把局部函数的名字让AO对象也有一个一样的成员名,把函数体赋值给这个属性
AO:{a:100,fn:function fn () {}}
function fm(a) {
console.log(a)
var a=20
function fn () {}
console.log(a)
}
var b=100
fm(b)
3.运行代码: 预编译过的就不在运行
AO:{a:100==>20,fn:function fn () {}}
console.log(a)//100
a=20
console.log(a)//20
我们浅看一个例子吧:
分析:
全局作用域运行代码时 也有预编译==>全局预编译
1.生成一个对象Global Object (GO)
GO:{}
2.把所有的全局变量 设置为GO的属性名
GO:{a:undefend}
3.把所有函数名 作为GO的成员名,把函数体赋值给这个成员
GO:{a:undefend,fn:function fn(){console.log(66)}}
4.执行代码
GO:{a:undefend==>20,fn:function fn(){console.log(66)}}
console.log(a) //undefined
a = 20 //
小知识:
全局预编译还有一步 ==> 不同的环境中运行js代码不一样
GO对象的成员全部浅拷贝给环境对象window
node.js 环境中没有这一步
拓展知识:关于访问成员 console.log(a) 访问的是GO对象的成员(作用域链中没有就报错)
console.log(window.a)不报错 原型链没有返回unfined