JavaScript 变量提升和函数提升

news/2024/7/7 23:36:25

文章目录

  • JavaScript 变量提升和函数提升
    • 作用域
    • 变量提升
    • 函数提升
    • 变量提升和函数提升的优先级

JavaScript 变量提升和函数提升

作用域

在JavaScript中,一个变量的定义与调用都是会在一个固定的范围中的,这个范围我们称之为作用域。

作用域可以分为:

  • 全局作用域:如果变量定义在全局环境中,那么在任何位置都可以访问到这个变量。
  • 函数作用域:如果变量定义在函数内部,那么只能在函数内部访问到这个变量。
  • 块级作用域:如果变量定义在一个代码块中,那么只能在代码块中访问到这个变量。

块级作用域是在ES6中新增的,需要使用特定的let或者const关键字定义变量。

//全局作用域
var a = "global variable";

function fn() {
    //函数作用域
    var b = "function variable";
    console.log(a);
    console.log(b);
}

{
    //块级作用域
    let c = "block variable";
    console.log(c);
}

变量提升

全局作用域和块级作用域使用比较简单,但是函数作用域不一样,主要是因为在函数内部使用var定义的变量时,函数中会存在变量提升的问题。

通过var关键字定义的变量会发生变量提升,变量提升是将变量的声明提升到函数顶部的位置,而变量的赋值并不会被提升。

问题

//代码一
var a = "hello";
(function() {
    console.log(a); //hello
})();
//代码二
var a = "hello";
(function() {
    console.log(a); //undefined
    var a = "hello js";
})();

代码一正常输出,但是代码二输出“undefined”,这是因为发生了变量提升。

//代码二等价于:
var a = "hello";
(function() {
    var a; //变量提升
    console.log(a); 
    a = "hello js"; //赋值未提升
})();

函数提升

不仅通过var定义的变量会出现提升的情况,使用函数声明方式定义的函数也会出现提升。

函数提升会将整个函数体一起进行提升,包括里面的执行逻辑。

函数表达式,是不会进行函数提升的。

函数

fn();
function fn() {
    console.log("hello"); 
}
//上面代码等价于:
function fn() {
    console.log("hello"); 
}
fn();

函数表达式

fn(); //ncaught TypeError: fn is not a function
var fn = function() {
    console.log("hello");
}

同时使用函数和函数表达式

show(); //你好
var show;
function show() {
    console.log("你好");
}
show = function() {
    console.log("hello");
}

由于函数声明会被提升,因此最后输出的结果为“你好”。

函数提升覆盖

function fn() {
    function bar() {
        return 3;
    }

    return bar();

    function bar() {
        return 8;
    }
}
console.log(fn()); // 8

代码中使用函数声明定义了两个相同的bar()函数。由于变量提升的存在,两段代码都会被提升至foo()函数的顶部,而且后一个函数会覆盖前一个bar()函数,因此最后输出值为“8”。

变量提升和函数提升的优先级

同时存在变量提升和函数提升,但是变量提升的优先级要比函数提升的优先级高。

function fn() {
    console.log(typeof foo); // function
    // 变量提升
    var foo = 'variable';
    // 函数提升
    function foo() {
        return 'function';
    }
    console.log(typeof foo); // string
}
fn();
//上面代码等价于:
function fn() {
    var foo;
    function foo() {
        return 'function';
    }
    console.log(typeof foo); // function
    foo = 'variable';
    console.log(typeof foo); // string
}
fn();

http://lihuaxi.xjx100.cn/news/663672.html

相关文章

WhatsApp居然有3个版本?深度详解区别!外贸圈获客神器用起来!

近两年,外贸圈用WhatsApp来营销获客,越来越火。不少走在前头的外贸人,已经尝到了甜头。但也有不少后来者,站在门外张望的时候,整个人都是蒙圈的。❓听说动不动要整几十个账号,还要花老长时间养号&#xff1…

《Linux Shell脚本攻略》学习笔记-第三章

3.1 简介 Unix为所有的设备和系统功能提供了文件形式的借口。可以通过这些特殊文件直接访问设备以及系统功能。 3.2 生成任意大小的文件 创建特定大小的文件最简单的方法就是利用dd命令。dd命令会克隆给定的输出内容,然后将一模一样的一份副本写入输出。 if表示输入…

【代码随想录】哈希表-golang

哈希表 from 代码随想录 hash表解法可以是slice,map…,目的是将时间复杂度降为O(1) 有效的字母异位词 给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。 排序 思路:直接重新声明字符的字节形式,然后对其进行…

冒泡排序算法的实现和优化~

冒泡排序算法: 算法思想: 反复扫描待排序记录序列,在扫描的过程中,顺次比较相邻的两个元素的大小,若逆序就交换位置 文字描述该算法: 以升序为例: 依次比较数组中相邻两个元素大小&#xf…

win10录屏文件在哪?如何找到录制后的文件

在工作和学习中,我们会遇到需要使用录屏工具录制电脑屏幕的情况,很多小伙伴在录制完win10电脑屏幕之后,找不到录制的视频文件。win10录屏文件在哪?今天小编教大家如何找到电脑录屏文件和录制win10电脑屏幕的方法,如果您…

Microsoft Graph PowerShell v2 发布公开预览版 - 新的身份验证方法,支持解除阻塞场景,脚本迁移工具

本篇接前一篇继续介绍,有些事情耽搁了所以发晚了。 为更多场景提供新的身份验证方法 1. 托管标识 在编写自动化脚本时,一个常见的挑战是管理用于保护服务之间通信的秘密、凭据、证书和密钥。允许模块获取受 Azure Active Directory 保护的 Azure 资源…

2023-01-16 mysql列存储引擎-多线程聚合-pack异步释放-需求分析

摘要: 目前在聚合多线程扫表的时, 遇到在线程切换时, 当LOCK_ONE策略导致其他线程的pack被释放引发crash的问题。并且当LOCK_ONE时, 每读取一个新的pack就会释放持有的旧的pack, 这样性能也不好. 考虑将pack的释放设计为异步的策略, 由独立的线程来完成对pack的释放. 多线程…

Go语言并发编程及依赖管理

目录🧡并发编程GoroutineCSP(Communicating Sequential Processes)🧡依赖管理依赖演变依赖管理三要素💟这里是CS大白话专场,让枯燥的学习变得有趣! 💟没有对象不要怕,我们new一个出来&#xff0…