函数的作用域以及预编译

一、函数的作用域

  • 函数作用域有点像单面镜(外面看不到里面,里面可以看到外面)
  • JS的特点:单线程、是 解释性语言 (翻译一行,执行一行)

二、预解析

JS预解析三部曲:语法解析 ⇒ 预编译 ⇒ 解释执行

JS 在执行之前会通篇扫描代码,看有没有语法语义错误(语法解析),如果没有,然后开始执行代码(预编译)

  • 通篇扫描 --> 语法分析
  • 通篇扫描之后开始执行 --> 预解析
test(); // 这种情况仍然会执行,就是预编译的作用

function test() {
    console.log('a');
}

// 在没有定义之前就使用结果为 undefined
console.log(a); // 能输出,是 undefined,还是因为预解析
var a = 10;

// 但是这种就不行,因为变量没有定义就执行 b is not defined
console.log(b);

三、变量和函数的提升

  1. 函数声明整体提升:不管你在哪调用函数,因为预解析会把函数提到逻辑的最前面,所以都是在函数的下面调用这个函数
  2. 变量声明提升
  3. imply global 暗示全局变量:即任何变量,如果变量未经声明就赋值,此变量就为全局对象所有
a = 123;
console.log(a); // 123
console.log(window.a); // 123
  1. 一切声明的全局变量,都是 window 属性
var b = 234;
console.log(b); --> console.log(window.b); // 234
  1. 如果在全局作用域下访问变量,就相当于访问 window.变量名
var a = b = 123; // 顺序:先把 123 赋值给 b;再 let a 声明变量;最后把 b 赋值给 a。
// 但是这就导致了,b 归全局作用域所有
console.log(window.a, window.b); // undefiend 123

var c = d = 234;
console.log(window.c, window.d); // 234 234

预编译四部曲

  1. 创建AO对象
  2. 找形参和变量声明,将变量和形参名作为AO属性名,值为 undefined
  3. 将实参值和形参统一
  4. 在函数体里面找函数声明,值赋予函数体

预编译练习提升的意思就是被优先执行了

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() {}
    function d() {}
}

// 预编译发生在函数执行的前一刻
fn(1);

/*
	1. 创建AO对象 (Activation Object) 
    2. 用形参和变量声明的名,作为AO对象的属性名,值统一为 undfiend
    AO {
        a : undefined,
        b : undefined
    }
    3. 把形参和实参的值统一
    AO {
        a : 1,
        b : undefined
    }
    4. 在函数体里面找函数声明,赋予函数体
    AO {
        a : function a() {}, // 只有函数声明会提升,函数表达式不会提升
        b : undefined,
        d : function d() {}
    }

    5. 函数执行
    AO {
        a : 123,
        b : function() {},
        d : function d() {}
    }
*/

在全局下会生成一个GO对象(Global Object)

function test() {
    var a = b = 123;
    console.log(a);
    console.log(window.b); // 123
    console.log(window.a); // undefined
}
test();

/*
	GO: {
        b: 123;
    }
    AO: {
        a: undefined
    }
*/

函数声明整体提升 变量声明提升

a = 100;
function demo(e) {
    function e() {}
    arguments[0] = 2;
    console.log(e); // 2
    if (a) { // a 是 undefined 所以这里 if 不会执行
        var b = 123;
        function c() {
            // 猪都能做出来
        }
    }
    var c;
    a = 10;
    var a;
    console.log(b); // undefined
    f = 123;
    console.log(c); // undefined
    console.log(a); // 10
}
var a;
demo(1);
console.log(a); // 100
console.log(f); // 123

/*
	GO {
        a: 100
        f: 123
        function demo() {}
    }
    AO {
            c: undefined
            a: 10
            e: 2
    }
*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

iteval

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值