语法分析
预编译
解释执行
函数申明会被提前申明
函数表达式,只是变量,不会被提前创建
全局变量属于window可以在任意位置被访问
在函数中未申明的变量都为全局变量
由var申明的变量,会在所有代码执行之前被申明
形参相当于在函数作用域中申明了变量
**未经申明的变量就赋值,就认为是全局变量,属于window
申明的在函数外部的全局变量,都为全局,都属于window属性**
函数先预编译再按照代码一行行执行
第一。预编译步骤:
(1)找全局(不考虑赋值)
(2) 找函数内部(不考虑赋值和条件是否成立)
变量申明–>形实参对应–>函数声明
第二。程序代码一行行执行
a = 12;
console.log(a); //12
window.a = 30;
console.log(a); //30
申明函数 提升整体,前后都可访问
预编译发生在函数执行前
AO执行期上下文
AO{
形参和变量的值为undefined
}
AO{
实参赋值给形参
}
AO{
找函数申明,把函数体赋给函数名
}
function fn(a){
console.log(a); //function a (){}
var a = 123;
console.log(a); //123
function a(){}
console.log(a); //123
var b = function(){}
console.log(b) //function b()}{}
function d(){}
}
fn(1)
AO{
a:undefined
b:undefined
}
AO{
a:1;
b:undefined
}
AO{
a:function(){}–>123
b:function(){}
d:function(){}
}
function test(a,b){
console.log(a); //function a(){}
console.log(c); //function c(){}
c= 0;
var c;
a = 3;
b= 2;
console.log(a) //3
console.log(b); //2
function c(){}
console.log(c); //0
function a(){}
console.log(a) //3
function b(){}
function d(){}
console.log(b); //2
console.log(d); //function d(){}
}
test(1);
// AO{
// a:undefined-->1-->function c(){}
// b:undefined-->function b(){}-->2
// c:undefined-->function c(){}-->0
// d:function(){}
// }
看一下完整的举例
/**
* 1先预解析为(变量声明-->实参对应-->函数申明)
* a: undefined-->实参赋值0-->function a()
* b: undefined
* 2.再一次一行行执行函数内的赋值的代码(除了函数声明)
*
*/
function test(a){
console.log(a); //function a
console.log(b) //undefined
var a = 1;
console.log(a) //1
function a(){
var a = 2;
}
console.log(a) //1
var b = function b(){} //这是关键点(容易错) 拆开分析 (先声明后赋值)
console.log(b) //function b
var b = 3;
console.log(b) // 3
}
test(0)
function shen(a,b){
console.log(a) //1
console.log(c) //function c
c= 0;
console.log(c) //0
var c;
console.log(c) //0
a = 5;
b = 6;
console.log(b); //6
function b(){}
function c(){}
console.log(c) //0
console.log(b); //6
}
shen(1)
需要注意函数内部和外部全局变量
a = 1;
function tryf(){
console.log(a);//undefined (var a = 3中的函数内部的变量a申明 提前)
a = 2;
console.log(a); //2
var a = 3;
console.log(a) //3
}
tryf();
var a;
console.log(a) //1(全局变量的a)
function test(){
console.log(b); //undefined
if(a){
var b = 2;
}
c = 3;
console.log(c) //3
}
var a;
test();
a = 1;
console.log(a) //1
在函数中未申明的变量都为全局变量
/**
* 未申明就赋值,为全局变量(window变量)
*
*/
function test(){
console.log(b); //undefined
if(a){
var b = 2;
}
c = 3; //未申明就赋值 全局变量 window
console.log(c) //3
}
var a;
test();
a = 1;
console.log(a) //1
console.log(c); //3(window)
//例子
/**
* 1、预解析为
* a:undefined(变量声明提前)-->(函数声明)function a()
* 2、按照代码一行行执行
*/
//return 的位置不同
function test1(){
return a; //function a
a = 1;
function a(){}
var a =2;
}
console.log(test1())
function test2(){
a = 1;
function a(){}
var a =2;
return a; //2
}
console.log(test2())
//例子
/**
* 1.全局 预解析
* a:undefined
* f:undefiend
* 2.函数预解析
* a:undefined
*
* 3.执行函数
*/
a = 1;
function test(){
arguments[0] = 2;
if(a){ //a为undefiend
var b = 3; //不管条件是否成立,预解析依然考虑b
}
var c;
a = 4;
var a;
console.log(b) //undefined
f = 5; //全局变量
console.log(c) //undefiend
console.log(a) //4
console.log(f) //5
}
var a; //全局变量
test(1)
console.log(a) //1
console.log(f) //5