预编译

函数执行过程

  • 1、检查通篇的语法错误
  • 2、预编译的过程
  • 3、解释一行,执行一行

变量和函数提升

函数声明整体提升,变量只有声明提升,赋值是不提升

// 变量只有声明提升,赋值是不提升
console.log(a);// undefined
var a;  // 没赋值被提升了

console.log(b);// undefined
var b = 1; // 赋值被提升了

// 函数声明整体提升
test();
function test() {
    console.log(1); // 1
}

显示与隐式全局变量

JS的全局变量声明方式:

  • 使用 var 显示声明的全局变量
  • 不使用 var 声明的隐式全局变量-暗示全局变量:imply global variable

两者的区别在于是否能通过 delete 操作符删除

// 全局变量
var a = 1; //  使用 var 显示声明全局变量a
b = 2; //  不使用 var 声明的隐式全局变量b

console.log(a, window.a); // 1 1 》 a = window.a
console.log(b, window.b); // 2 2 》 b = window.b

// 存储过程
window = {
    a : 1,
    b: 2
}

// 显式声明的全局变量不能被删除
console.log(delete a); // false

// 隐式声明的全局变量可以被删除
console.log(delete b); // true

// 删除情况
console.log(typeof a); // number
console.log(typeof b); // undefined

内部声明变量

// 变量未声明,在函数内部直接赋值,被提升到全局
function test() {
    var a = b = 1;
}
test();
console.log(b); // 1
console.log(window.a); // undefined
console.log(a); // ReferenceError: a is not defined

预编译过程:AO与GO

(1)AO:activation object,活跃对象,函数上下文。创建AO过程:

  • 1、寻找形参和变量声明
  • 2、实参值赋值给形参
  • 3、找函数声明
  • 4、执行赋值

(2)GO:global object,全局上下文(等于window)。创建GO过程:

  • 1、找变量声明
  • 2、找函数式声明
  • 3、执行赋值

(3)AO示例分析

function test(a) {
    console.log(a); // ƒ a() {}
    var a = 1;

    console.log(a); // 1
    function a() {}
    console.log(a); // 1

    var b = function(){}
    console.log(b); // ƒ (){}

    function d() {}
}

test(2);

AO = {
    a: undefined >
        2 >
        function a(){} >
        1,
    b: undefined >
        function () {},
    d: function d() {},
}
function test(a, b) {
    console.log(a); // 1
    c = 0;
    var c;
    a = 5;
    b = 6;
    console.log(b); // 6
    function b() {}
    function d() {}
    console.log(b); // 6
}

test(1);

AO = {
    a: undefined > 
        1 >
        5,
    b: undefined > 
        function b(){} >
        6,
    c: undefined > 
        0,
    d: function d() {}
}

(4)GO示例分析

var a = 1;
function a () {
    console.log(2);
}
console.log(a); // 1

GO = {
    a: undefined > function a() {} > 1
}
console.log(a, b); // ƒ a() {} undefined
function a() {}
var b = function() {}

GO = {
    b: undefined,
    a: undefined > function a() {}
}

(5)AO与GO示例

function test() {
    var a = b = 1;
    console.log(a); // 1
}

test();

GO = {
    b: 1
}

// AO中有找AO,没有找GO
AO = {
    a: undefined > 1
}
var b = 3;
console.log(a); // function a(){...}
function a(a) {
    console.log(a); // function a() {}
    var a = 2;
    console.log(a); // 2
    function a() {}
    var b = 5;
    console.log(b); // 5
}

a(1);

GO = {
    b: undefined > 3,
    a: function a(){...}
}

AO = {
    a: undefined > 1 > function a() {} > 2,
    b: undefined > 5,
}
a = 1;
function test() {
    console.log(a); // undefined
    a = 2;
    console.log(a); // 2
    var a = 3;
    console.log(a); // 3
}
test();
var a;

GO = {
    a: undefined > 1,
    test: function test() {...}
}

AO = {
    a: undefined > 2 > 3
}
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

GO = {
    a: undefined > 1,
    test: function test() {...},
    c: 3 // 函数中没有var声明,直接提到GO为全局变量
}

AO = {
    b: undefined
}
function test() {
    return a;
    a = 1;
    function a() {}
    var a = 2;
}
console.log(test()); // function a() {}

AO = {
    a: undefined > function a() {}
}
function test() {
    a = 1;
    function a() {}
    var a = 2;
    return a;
}
console.log(test()); // 2

AO = {
    a: undefined > function a() {} > 1 > 2
}
a = 1;
function test(e) {
    function e() {}
    arguments[0] = 2;
    console.log(e); // 2
    if (a) { // 预编译不看if,只有执行才会检查
        var b = 3;
    }

    var c;
    a = 4;
    var a;
    console.log(b); // undefined
    f = 5;
    console.log(c); // undefined
    console.log(a); // 4
}

var a;
test(1);
console.log(a); // 1
console.log(f); // 5

GO = {
    a: undefined > 1,
    test: function test() {...},
    f: 5 // 执行时 f=5 直接写过来
}

AO = {
    e: undefined > 1 > function e() {} > 2,
    b: undefined,
    c: undefined,
    a: undefined > 4
}