// 预编译发生在函数执行的前一刻
原式
function fn(a){
console.log(a);
var a = 123;//变量声明
console.log(a);
function a (){}//函数声明
console.log(a);
var b = function(){} //变量声明
console.log(b);
function d(){}//函数声明
}
fn(1);
1.创建AO对象(Activation Object)(执行期上下文)---函数产生的存储空间库
AO{
}
2.找形参和变量声明,值为undefined(将变量和形参名作为AO属性名)
AO{
a:undefined,
b:undefined,
}
3.(实参值放形参里面去)将实参值和形参统一
AO{
a:1,
b:undefined,
}
4.在函数体里面找函数声明,值赋予函数体
AO{
a:function a() {},
b:undefined,
d:function d() {}
}
预编译后
function fn(a){
console.log(a);//----------打印的a是AO里面的a:function a() {},
var a = 123;
console.log(a);//--------打印的a是真正的存储值,即AO里面的a:function a() {},变成了a=123
AO{
a:123,
b:undefined,
d:function d() {}
}
function a (){}
console.log(a);//------------打印123
var b = function(){}
AO{
a:function a() {},
b:function(){},
d:function d() {}
}
console.log(b);//-------------打印 b:function(){},
function d(){}
}
fn(1);
例子
function test(a,b) {//第一次访问
console.log(a);//-------1
c = 0;
var c;//第一次访问
a = 3;//没打印
b = 2;
console.log(b);//-----------2
function b(){}//第一次访问
function d(){}//第一次访问
console.log(b);//-----------2
}
test(1);
预编译过程
AO{
a:undefined,
b:undefined,
c:undefined,
}
AO{
a:1,
b:undefined,
c:undefined,
}
AO{
a:1,
b:function b(){},
c:undefined,
d:function d(){},
}
执行
AO{
a:1,
b:function b(){},
c:0,
d:function d(){},
}
AO{
a:3,(没调用出来)
b:2,
c:0,
d:function d(){},
}
例子
function test(a,b) {
console.log(a);//function a(){}
console.log(b);//undefined
var b = 234;
console.log(b);//234
a = 123;
console.log(a);//123
function a() {}
var a;
b = 234;
var b = function() {}
console.log(a);//123
console.log(b);//function() {}
}
test(1);
预编译最后一步
AO{
a:function a(){}
b:undefined,
}
开始执行
预编译不仅发生在函数体系里,还在全局,如果变量未经声明就赋值,那么要放在全局GO里面
1.生成了一个GO对象,Global Object //GO====window
例子
打印b
function test() {
var a = b = 123;
console.log(window.b);//----------123
}
test();
打印a
function test() {
var a = b = 123;
console.log(window.a);//---undefined
}
test();
例子
console.log(test);
function test(test) {
console.log(test);
var test = 234;
console.log(test);
function test() {
}
}
test(1);
var test = 123;
AO{ test:234 }
例子
var global =100;
function fn() {
console.log(global);
}
fn();
GO{
global:100,
fn:function(){...}
}
AO{
AO没有,往上找全局的global=100
}
例子
GO{
第一步:global:undefined;
第二步: global:100
}
global = 100;
function fn() {
console.log(global);//undefined
global = 200;
console.log(global);//200
var global = 300;//AO的变量声明变为undefined;
}
// AO{
// global:undefined;
// }
fn()
var global;
例子
function test() {
console.log(b);//undefined
if(a) {
var b = 100;//变量声明
}
console.log(b);//undefined
c = 234;
console.log(c);//234
}
var a;
test();//函数开始执行AO
a = 10;
console.log(c);//234
// AO{
// b:undefined
// }
1例子
function bar() {
return foo;//函数提升,相当于打印foo====function foo() {}
foo = 10;
function foo() {}
var foo = 11;
}
console.log(bar())//f foo(){}
2例子
console.log(bar());======11
function bar() {
foo = 10;
function foo() {}
var foo = 11;
return foo;
}
例子
console.log(b);//undefined
var b = function(){}//变量声明,值undefined
例子(2,undefined,undefined,10,100,123) if里面·不能声明·function
GO{
a:100;
demo:function(){}
f:123
}
a = 100;
function demo(e) {
function e() {}
arguments[0] = 2;
console.log(e);//2
if(a) {
var b = 123;
function c() {
//版本不支持
}
}
var c;
a = 10;
var a;
console.log(b);//undefined
f = 123;
console.log(c);//undefined function
console.log(a);//10
}
var a;
demo(1);
console.log(a);//100
console.log(f);//123
AO{
e:2
b:undefined,
c:undefined,fnc,
a:10
}
难例子隐式类型转换
var str = false + 1;
document.write(str);//false转换为数字为0,1
var demo = false == 1;
document.write(demo);//false
if(typeof(a)//&& - true +(+undefined + "") {
###### //结果字符串"undefined"&&"NaN",布尔值
document.write("学会了");
}
if(11 + "11" * 2 == 33) {
document.write("学会了");
}//乘号两边转化为数字类型
!!" " + !!"" - !!false||document.write("学废了")
true +false - false =1或运算符找到真就返回,不往后走
例子
(window.foo || (window.foo = "bar"));
window.foo = "bar"//,先读括号里面