JavaScript基础:预编译

预编译

JavaScript是单线程+解释型语言

// 预编译:输出a
// 函数声明整体提升
test();
function test(){
    console.log('a');
}

// 预编译:输出undefined
// 变量声明提升
console.log(a);
var a = "123";
  1. imply global
    暗示全局变量:即任何变量,如果有变量未声明就赋值,此变量就为全局对象所有。
    全局对象是window,可以添加属性。
    例如:
a = 123; // window的属性
console.log(a);
var a = b = 123;

第三行语句的执行过程:(1)先把123赋值给b;(2)再声明a(3)再把b的值赋给a;
b是window的属性
2. 一切声明了的全局变量,全是window的属性

var a = 123;
console.log(window.a);

window就是全局的域

函数的预编译

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对象
AO{
}
  1. 找形参和变量声明,将变量和形参名作为AO属性名,值为undefined
AO{
	// a是形参a,不是变量a
	a:undefined,
	b:undefined
}
  1. 将实参值和形参统一
AO{
	// a是形参a,不是变量a
	a:1,
	b:undefined
}
  1. 在函数体里面找函数声明,值赋予函数体
AO{
	// a是函数声明a,不是形参a,也不是变量声明a
	a:function a(){},
	b:function(){},
	d:function d(){}
}

以上程序的执行过程为

  • 第二行console.log(a);输出的是预编译之后AO里的a,也就是function a(){}
  • 程序执行到第四行console.log(a);时,预编译过程没有编译第三行代码中的变量声明a,此时存入AO对象
AO{
	// a是变量声明a
	a:123,
	b:function(){},
	d:function d(){}
}

因此该行输出的是123

  • 第六行console.log(a);执行时,由于第五行代码已经预编译过,因此此时AO对象中的a仍然是123
  • 第八行console.log(b);执行时,第七行的代码已经预编译过,因此输出AO对象中的b,即function(){}

示例2:

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);

示例3:

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;
    var b = function(){} // 函数表达式不能提升
    console.log(a); // 123
    console.log(b); // function(){}
}
test(1);

全局预编译

  1. 生成GO对象:global object
  2. 找变量声明,将变量作为AO属性名,值为undefined
  3. 找函数声明,值赋予函数体

未经声明就赋值的对象都是window的属性

示例4:

// GO{
//     test:123
// }
console.log(test); // function test(test){...}
function test(test){
    console.log(test); // function test(){}
    var test = 234; // 未提升
    console.log(test); // 234
    function test(){}
}

// AO{
//     test:234
// }
test(1);
var test = 123;

示例五:

// GO{
//     a:undefined,
//     tets:function test(){...},
//     c:234
// }

function test(){
    console.log(b); // undefined
    if(a){ // 预编译不管if等语句,直接看块内语句是不是需要预编译
        var b = 100;
    }
    console.log(b); // undefined
    c = 234;
    console.log(c); // 234
}

var a;

// AO{
//     b:10,
// }
test();
a = 10;
console.log(c); // 234

知识和示例来源:渡一

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值