变量声明提升 Vs. 函数声明提升

JavaScript函数声明大比拼 阅读详情

1. 变量声明提升

      先看以下代码:

1)var in_window = "a" in window; console.log(in_window); 

2)var in_window = "a" in window; console.log(in_window); if(!("a" in window)) { var a = 1; }

3)var a; var in_window = "a" in window; console.log(in_window); if(!("a" in window)) { a = 1; }

      控制台输出的结果分别是:false true true。如何解释? 这是由于在js的变量作用域中有个规则:所有变量声明都在范围作用域的顶部!也就是说,在2)代码中,if语句块内的申明的变量a,会自动提到上面去申明。其等价于3)。

      由上述的分析可知,可以理解下面代码的输出结果是undefined。

if(!("a" in window)) { var a = 1; } console.log(a); //undefined  
该代码其实相当于:

var a; if(!("a" in window")) { a = 1; } console.log(a);

再试一次:

var s = '';
if (false) {
    var a = 1;
}

      浏览器中的调试结果如下:

      有图有真相。变量a的声明的确提升了。

      巩固题: 

     

var s = ''; while(false) { var a = 1; } console.log(a); //undefined

      if(!("a" in window)) { a = 1 } console.log(a); //1

      console.log(a); //报错,"ReferenceError: a is not defined."

2. 函数声明提升

      定义函数有两种方式:一种是函数申明,另一种是函数表达式。

函数申明形式:

function functionName(arg0, arg1, arg2) {
 //函数体
 }

函数表达式形式:

var functionName = function(arg0, arg1, arg2) {
 //函数体 
}

关于函数申明,它有一个重要特征就是函数声明提升,看下面的例子。

sayHi();
function sayHi() {
    console.log("hi");
}

      浏览器中的调试结果如下: 发现函数sayHi已经被声明了,并且其值为sayHi函数。第一行代码执行后,输出hi。

 

      若采用函数表式的形式,此时我们能看到变量声明提升的效果。

sayHi();
var sayHi = function() {
    console.log("hi");
}

      在浏览中的调试效果如下:发现变量sayHi提升了,它的值是undefined,第一行代码执行的话,会报错:"TypeError:undefined is not a function"。

      接下来的例子就很好理解。

     

if(!("a" in window)) { var a = function() { window.a = 1; } } console.log(a); //undefined
<pre name="code" class="html"> 该代码等价于:
 var a; if(!("a" in window)) { a = function() { window.a = 1; } } console.log(a); 其实无论if语句块中的a被定义成何种类型的值,a的申明都提前了。(变量提升)
 

      将上述代码变形如下:

   

  if(!("a" in window)) { function a() { window.a = 1; }} console.log(a); //function a() { window.a = 1;}(函数申明提升)

      由此可以总结出,所有函数声明也在范围作用域的顶部。那么函数声明和变量声明,哪个的优先级高呢?

3. 变量声明 VS 函数声明

      如下图对比所示:函数声明会覆盖变量声明。

     VS    VS   

      但是如果在变量声明的同时,对变量进行初始化,情况会有所不同。对同一个变量名,声明变量同时初始化变量优先级高于函数声明。

    VS      VS   

      再练几题:

function a() { return false; }
var s = '';
if(a()) {
    var a = 1;
}
console.log(a);

      上述代码输出的a值为:function a() { return false; }
function a() { return true; }
var s = '';
if(a()) {
    var a = 1;
}
console.log(a);

      上述代码输出的a值为:1
function a() { return true; }
var a;
var s = '';
if(a()) {
    a = 1;
}
console.log(a);


      上述代码输出的a值为:1

      由对上述代码的分析:可以总结出如下规律:

1)变量声明提升:变量申明在进入执行上下文就完成了。

      只要变量在代码中进行了声明,无论它在哪个位置上进行声明, js引擎都会将它的声明放在范围作用域的顶部;

2)函数声明提升:执行代码之前会先读取函数声明,意味着可以把函数申明放在调用它的语句后面。

      只要函数在代码中进行了声明,无论它在哪个位置上进行声明, js引擎都会将它的声明放在范围作用域的顶部;

3)变量or函数声明:函数声明会覆盖变量声明,但不会覆盖变量赋值。

      同一个名称标识a,即有变量声明var a,又有函数声明function a() {},不管二者声明的顺序,函数声明会覆盖变量声明,也就是说,此时a的值是声明的函数function a() {}。注意:如果在变量声明的同时初始化a,或是之后对a进行赋值,此时a的值变量的值。

eg: var a; var c = 1; a = 1; function a() { return true; } console.log(a); //1


原文参考:变量声明提升 Vs. 函数声明提升

JavaScript变量声明、作用域与提升的底层原理 JavaScript中的变量声明不是简单的语法糖,而是引擎执行上下文初始化的核心环节。其本质涉及环境记录创建、绑定注册与初始化分离,直接决定内存分配和生命周期管理。词法作用域在代码解析阶段即静态确立,配合动态构建的作用域链实现标识符查找;而‘提升’实为声明登记与初始化时机的差异——var在函数级提前初始化为undefined,let/const则引入暂时性死区(TDZ)保障块级安全性。这些机制共同支撑闭包、模块隔离、React Hook依赖追踪及小程序权限校验等关键场景,是理解ReferenceError、 阅读详情

相关推荐

计算机视觉之ResNet

RestNet是2015年由微软团队提出的,在当时获得分类任务,目标检测,图像分割第一名。该论文的四位作者何恺明、张祥雨、任少卿和孙剑如今在人工智能领域里都是响当当的名字,当时他们都是微软亚研的一员。实验结果显示,残差网络更容易优化,并且加深网络层数有助于提高正确率。在ImageNet上使用152层的残差网络(VGG net的8倍深度,但残差网络复杂度更低)。对这些网络使用集成方法实现了3.75%的错误率。获得了ILSVRC 2015竞赛的第一名。原文链接这是一篇计算机视觉领域的经典论文。

十年以上架构设计经验,专注于软件架构和人工智能领域,对机器视觉、NLP、音视频等领域都有涉猎 2万+

for(var 变量 in 对象)

for(var 变量 in 对象) for in循环的次数是由对象中的属性个数决定的,例如 var obj = { name:'孙悟空', age:'5000', character:'吃桃子就咬一口' } var time = 0; for(var i in obj){ time++; } console.log(time); 这里我们看到对象里有三个属性,就for循环就循环了三次。 多次执行变量的赋值是什么? var obj = { na

blc_God的博客 6514

鸿蒙5.0进阶开发:UI开发-不依赖UI组件的全局自定义弹出框 (openCustomDialog)(推荐)

本文介绍通过入参形式为ComponentContent创建自定义弹出框............

AyomQAQ的博客 1850

shell脚本学习四(结构化命令for、while、util)

for命令: for var in list do commands done $user 变量保持了其值,也允许我们修改它的值,并在for命令循环之外跟其他变量一样使用 从命令读取值: ...

服务猿 1373

ABAQUS单元刚度矩阵输出全攻略:从理论到实践(含MTX/DAT文件对比)

本文详细解析了ABAQUS中单元刚度矩阵的输出方法,涵盖理论原理、MTX与DAT文件格式对比及二次开发应用。通过具体操作步骤和性能优化建议,帮助用户高效获取并利用刚度矩阵数据,特别适合需要进行有限元分析验证和二次开发的工程师。

lg888的博客 1006

Springer期刊LaTeX模板中参考文献格式选择与编译错误的快速修复指南

本文针对Springer期刊LaTeX模板中参考文献编译后显示问号的常见问题,提供了快速修复指南。核心在于正确选择并配置与期刊匹配的参考文献格式文件(.bst),并执行标准的四步编译流程。文章详细解释了问题根源,并给出了从查找正确.bst文件到修改代码、执行编译的完整解决方案,帮助作者高效解决投稿中的技术障碍。

weixin_29266007的博客 402

java for循环的几种写法

J2SE 1.5提供了另一种形式的for循环。借助这种形式的for循环,可以用更简单地方式来遍历数组和Collection等类型的对象。本文介绍使用这种循环的具体方式,说明如何自行定义能被这样遍历的类,并解释和这一机制的一些常见问题。 在Java程序中,要“逐一处理”――或者说,“遍历”――某一个数组或Collection中的元素的时候,一般会使用一个for循环来实现(当然,用其它种类的循环

王意林的专栏 13万+

别再手动上传了!用宝塔面板的‘Let‘s Encrypt’免费SSL证书,3分钟自动续期

本文详细介绍了如何利用宝塔面板的‘Let‘s Encrypt’功能实现SSL证书的自动申请和续期,3分钟完成配置即可永久免费使用。通过对比不同SSL证书方案,突出Let's Encrypt的免费、自动续期和高安全性优势,特别适合个人博客和中小企业官网。

weixin_30415113的博客 150

变量提升与函数提升

一、变量提升   变量提升即将变量声明提升到它所在作用域的最开始的部分。 通过var定义(声明)的变量,在定义语句之前就可以访问到; 值:undefined; console.log(a); //undefined var a = 1;   因为有变量提升的缘故,上面代码实际的执行顺序为: var a; console.log(a); a = 1; 二、函数提升   js中创建函数有两种方式:函数声明式和函数表达式   1、函数声明提升 function fun() { con

qq_43692768的博客 1万+

❤️爆肝十二万字《python从零到精通教程》,从零教你变大佬❤️(建议收藏)

文章目录强烈推荐系列教程,建议学起来!!一.pycharm下载安装二.python下载安装三.pycharm上配置python四.配置镜像源让你下载嗖嗖的快4.1pycharm内部配置4.2手动添加镜像源4.3永久配置镜像源五.插件安装(比如汉化?)5.1自动补码神器第一款5.2汉化pycharm5.3其它插件六.美女背景七.自定义脚本开头八、这个前言一定要看九、python入门十、python缩进十一、Python注释1.单行注释2.多行注释十二、Python 变量1.变量定义理解2. 变量名命名3. 分

全栈川川 26万+

投稿前利用GPT-5.5给论文做一次深度校对,投稿命中率翻倍!

3)一致性:请对比摘要的结论与正文(如果我也提供了正文),确保完全一致。请严格检查结果部分,确保客观性:1)纯粹性检查:标出所有包含“为什么”(解释)或“这意味着什么”(暗示)的主观语句,这些应移至讨论部分。请你帮我评估讨论部分的深度:1)解释与对比:检查每一项主要结果是否都解释了原因,并引用了前人研究进行对比(一致或相悖)。我见过太多人把校对理解为检查错别字了,实际上,校对要看的远不止这个,像逻辑是否连贯、术语是否前后一致、图表有没有被正确引用等等的这些细节,往往决定了文章是秒被拒,还是能顺利进入外审。

智能AI让学术科研更容易 412

【前端】JavaScript 变量声明与函数声明的提升机制:深入探讨提升优先级与其行为

JavaScript 中的提升机制是一个重要且复杂的概念,理解函数声明与变量声明的提升优先级对于避免代码中的潜在错误至关重要。提升机制使得函数声明在变量声明之前被提升,而 var 声明的变量只会在作用域中被初始化为 undefined,并在代码执行阶段完成赋值。因此,理解这些细节可以帮助开发者编写出更为稳定、健壮和易于维护的代码。 为了最大程度地减少因提升带来的问题,建议开发者尽量使用 let 和 const,并确保函数和变量之间没有命名冲突。 2024.11.25-✍

禅宗里有一个词叫做“因缘和合”。 所谓因缘,是指事件要发生所必须的条件。因缘和合就是当你聚集了这件事的一切条件,它就会自然而然的发生。“它就会自然而然的发生”,这种朴素而坚定的价值观让我们感到无比安心,安心到可以不用有任何担心焦虑。 1098

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

javascript变量声明

zhuanzi:http://qingbob.com/blog/%E8%B0%88javascript%E5%8F%98%E9%87%8F%E5%A3%B0%E6%98%8E 之前的面试中遇到过一道面试题 var a =10;(function(){ console.log(a);var a =20;})() 短短5行代码log的结果是什么? 如果把var a = 20;...

dianzongfan5428的博客 139

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

变量提升

变量声明提升 Vs. 函数声明提升 1. 变量声明提升       先看以下代码: 1)var in_window = "a" in window; console.log(in_window);  2)var in_window = "a" in window; console.log(in_window); if(!("a" in window)) { var a = 1; } 3)

likeuzi的博客 316

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

函数声明 VS. 函数表达式

昨晚室友扔我一道前端JS面试题,我仔细看了一下,给出了答案,果不其然,有两个地方答错了,这里就记录一下。题目function Foo(){ getName = function(){alert(1)}; return this; } Foo.getName = function(){alert(2)}; Foo.prototype.getName = function(){alert

Microstrong 925

函数表达式和函数声明有什么区别?

1.背景介绍 函数声明 函数声明可以定义命名的函数变量,而无需给变量赋值。函数声明是一种独立的结构,不能嵌套在非功能模块中。可以将它类比为 变量声明。就像变量声明必须以“var”开头一样,变量声明必须以“function”开头。函数名在自身作用域和父作用域内是可获取的。   函数表达式 函数表达式将函数定义为表达式语句(通常是变量赋值)的一部分。通过函数表达式定义的函数可以是命名的,也可...

storyoco的博客 1万+

JS变量提升

javascript引擎在执行代码前 (预编译阶段),会先收集所有声明并提升到作用域

weixin_75241856的博客 1000

C语言程序结构与函数声明详解

深入解析C语言的程序组成,涵盖源文件、函数、变量声明及主函数的作用。通过实例讲解函数原型、定义与注释规范,帮助开发者理解代码组织方式和编程规范,提升程序可读性与维护性。

weixin_42163404的博客 820

函数的提升(声明VS表达式)

待定

liupei2011的专栏 938

从面试题看JS变量提升

变量提升是JavaScript编译阶段将声明提前放入内存的机制。var声明提升后初始化为undefined,函数声明整体提升,函数表达式不具备此特性。let和const也有提升,但进入暂时性死区,声明前访问会报错。

im_AMBER的博客 865

浅谈js变量声明

—-浅谈js变量声明   或者确切地说应该是变量声明以及与之相关的一些东西。   这里只谈四种声明方式(var,function,let,const),其它的声明方式以后有接触再更新。 ‘var’ VS ‘let’   var貌似是最常用的,在ES6还没出来的时候只能用var来声明一个变量,var声明的变量只有函数能对其构成作用域。这样的话会出现一些意料之外的问题,比如如果你的页面里有一...

夜落初阳,书写欢乐 1556
上一篇: 解决SVN安装语言包后无法选择中文的问题
下一篇: char byte int互转
八阿哥别走
博客等级 码龄16年 8粉丝 21原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值