JavaScript作用域、作用域链、预解析(变量提升)几个小练习

本文深入探讨了JavaScript中的作用域概念,包括变量作用域、全局变量、局部变量及作用域链的查询机制。同时,详细讲解了JavaScript的预解析过程,即预编译和声明提前,以及这一特性如何影响代码的执行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

作用域

变量的作用域:变量在一个范围内是有效的,这个范围就是变量的作用域。

​ 在此作用域内,可以使用、改变变量。

全局变量:在函数外部定义的变量、在函数内部没有var声明的变量。

局部变量:在函数内部定义的变量。

作用域链

​ 作用域中查询变量时,从内到外依次查找,找到停止,没找到就一直查找到最外层。

JavaScript预解析(预编译、声明提前)

浏览器中有解析js代码的程序===>js引擎

​ ①先进行预编译,把js代码转换成机器码。

​ JavaScript代码在执行之前,会将所有变量、函数声明提升到所在作用域最前面初始化为undefined。

​ (根据var、function去找,然后放入仓库中,要用的时候去找)

​ ②解释执行,由上至下,逐行执行js代码

每遇到一个新的作用域,都会执行这两步。

例1:

    alert(a);   //undefined
    alert(b);   //undefined
    alert(c);   //undefined
    alert(fn1); //弹出整个代码块
    var a = 1;
    alert(a);   //赋值将undefined覆盖,弹出1
    var b = 2;
    var c = 3;
    function fn1() {
        alert("fn1");
    }

例2:

	alert(a);	//function a() {alert("fn1")}
    var a = 10;
    alert(a);	//10
    function a() {
        alert("fn1");
    }
    a();	//报错

执行步骤:

​ 1、先将变量和函数找到,放进仓库。

a = undefined

​ a = function a() {alert(“fn1”)}

​ 变量和函数同名,保留函数。

​ 函数同名,保留后者。

​ 2、逐行执行代码。

​ alert(a) ===> function a() {alert(“fn1”)}

​ a = 10 ===> 改变仓库中的值

​ alert(a) ===> 10

​ a() ===> a再调用时已经变成了10,报错

在这里插入图片描述

例3:

	var a = 10;
    function fn(){
        alert(a);	//undefined
        var a = 20;
    }
    fn();
    alert(a);	//10

执行步骤:

​ 1、先将变量和函数找到,放进仓库。

​ a = undefined

​ fn = function fn() {…}

​ 2、逐行执行代码。

​ a = 10

​ fn() 每个函数都是一个作用域快

​ 1 找变量、函数

​ a = undefined

​ 2 逐行执行

​ alert(a) ===> undefined

​ a = 20

​ alert(a) ===> 10

例4:

    function Foo() {
        // 函数表达式    没有用var定义    全局变量
        getName = function () {
            alert(1);
        };
        return this;
    }
    // 静态方法
    Foo.getName = function () {
        alert(2);
    }
    // 公共方法
    Foo.prototype.getName = function () {
        alert(3)
    }
    // 函数表达式
    var getName = function () {
        alert(4);
    }
    // 函数声明
    function getName() {
        alert(5);
    }
    console.log(Foo.getName())  //undefined,因为没有return

    getName();  //弹出4(变量提升)

	Foo().getName();  //弹出1(this指向window),全局的getName被Foo()中的getName覆盖

    new Foo.getName();  //弹出2,相当于new function(){ alert(2)}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值