预编译

247 阅读3分钟

// 预编译发生在函数执行的前一刻

原式

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"//,先读括号里面