JS 作用域和预解析

作用域

        通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突。

作用域分为全局作用域局部作用域

es6的时候新增了块级作用域{ }。

全局变量和局部变量

        根据作用域的不同,变量也可分为全局变量局部变量

        全局变量:在全局作用域下声明的变量,在全局都可以使用。

  • 在全局作用域下var声明的变量是全局变量
  • 如果在函数内部没有声明直接赋值的变量也属于全局变量(不建议使用)

        局部变量:在局部作用域下声明的变量(在函数内部定义的变量)只能在函数内部使用。

  • 在函数内部var声明的变量就是局部变量

二者区别

        全局变量:在任何一个地方都可以使用,只有在浏览器关闭时才会被销毁,因此比较占内存
        局部变量:只在函数内部使用,当其所在的代码块被执行时,会被初始化;当代码块运行结束后,就会被销毁,因此更节省内存空间。

作用域链

        内部函数访问外部函数的变量,采取的是链式查找的方式来决定取哪个值,这种结构我们称为作用域链 (就近原则)

下面这个代码,就近原则输出的是20。

预解析

js引擎分为两步:预解析 代码执行

(1)预解析  js引擎会把 js中所有的 var 还有function 提升到当前作用域的最前面

(2)代码执行  按照代码书写的顺序从上往下执行

预解析分为变量预解析(变量提升)函数预解析(函数提升)

变量预解析

变量提升 就是把所有的变量声明提升到当前的作用域最前面,不提升赋值操作。

console.log(num)  
var num=10;//相当于执行了以下代码var num;   //预解析,把变量声明提升上来
console.log(num);
num=10;  //赋值不提升

        上面这段代码预解析时会把变量声明提升到最前面,但不提升赋值操作,所以上面那个代码console.log(num)时num还没有被赋值,会输出undefined。

        注意函数表达式,是用一个变量存储函数的,预解析时只提升变量声明不提升变量赋值。所以函数表达式调用必须要写在函数表达式的下面,不然会出错。

// 函数表达式 调用必须要写在函数表达式的下面
fun();   //所以这里会输出undefined
var fun=function(){console.log(22);   
}//相当于执行了以下代码
var fun; //提升了变量声明
fun();
fun=function(){  //变量赋值不提升console.log(22);
}

函数预解析

函数提升 就是会把函数声明提升到当前作用域最前面,不提升调用操作。

fn();
function fn(){console.log(22)
}//预解析
//相当于执行下面的代码,所以不会报错
function fn(){   //函数声明console.log(22)
}
fn();   //函数调用

一道易错题:

f1();
console.log(c);
console.log(b);
console.log(a);
function f1(){var a=b=c=9;console.log(a);console.log(b);console.log(c);
}// 预解析
//相当于以下代码
function f1(){  //把函数声明提升var a;  //变量提升a=9;b=9;c=9;console.log(a);console.log(b);console.log(c);
}
f1();  //调用f1()输出9 9 9
console.log(c);
console.log(b);
console.log(a);//外面输出的是 9 9 undefined 

这道题易错点是:

        var a=b=c=9; 相当于var a=9;b=9;c=9;

        而不是集体声明,集体声明应该为 var a=9,b=9,c=9;

因为在函数内部没有声明直接赋值的变量也属于全局变量,所以b和c是全局变量。a是在函数内部声明的,所以a是局部变量。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/334457.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Win10 自带微软输入法怎么切换成简体字 快捷鍵是什么?

环境: Win10专业版 问题描述: 微軟輸入法怎麽切換中文簡體 快捷鍵,之前不小心按了快捷键 解决方案: 1.按CtrlShiftF快捷键转换简体字或繁体字 2.可以在“设置-时间和语言-区域和语言-语言-中文(中华人民共和国&a…

最全最详细ChatGPT预设词Prompt教程

使用指南 1、可直复制使用 2、可以前往已经添加好Prompt预设的AI系统测试使用(可自定义添加使用) https://ai.sparkaigf.com 雅思写作考官 我希望你假定自己是雅思写作考官,根据雅思评判标准,按我给你的雅思考题和对应答案给我…

小H靶场笔记:DC-6

DC-6 January 6, 2024 12:06 PM Tags: nmap提权,WordPress Owner:只惠摸鱼 信息收集 apr-scan和nmap探测主机后,发现靶机ip:192.168.199.136,端口22和80开放 扫描端口服务、版本、操作系统、默认脚本扫描 扫描开…

CMake入门教程【核心篇】动态库与静态库的差别

😈「CSDN主页」:传送门 😈「Bilibil首页」:传送门 😈「动动你的小手」:点赞👍收藏⭐️评论📝 文章目录 1.概述2.动态库(Shared Libraries)主要特点使用场景3.静态库(Static Libraries)主要特点

权威报告|得帆信息入选甲子光年《2023信创软件品牌影响力研究报告》

近日,国内知名科技产业智库甲子光年发布了《2023信创软件品牌影响力研究报告》,报告全面、深度探究了信创软件的发展历程与现状,讨论主要驱动力的变化,以及国内软件厂商在国内市场的品牌影响力,并寻找当前信创落地遇到…

【无标题】PDF编辑软件哪个好用?4款PDF编辑器分享!

PDF编辑软件哪个好用?在我们的日常办公中,编辑PDF文件是非常方便的一项功能。通过编辑PDF,我们可以对文档进行修改和调整,添加或删除内容,以及进行格式和布局的更改。这样,我们可以更好地符合我们的需求和要…

YOLOv8改进 | Neck篇 | 利用ASF-YOLO改进特征融合层(适用于分割和目标检测)

一、本文介绍 本文给大家带来的改进机制是ASF-YOLO(发布于2023.12月份的最新机制),其是特别设计用于细胞实例分割。这个模型通过结合空间和尺度特征,提高了在处理细胞图像时的准确性和速度。在实验中,ASF-YOLO在2018年数据科学竞赛数据集上取得了卓越的分割准确性和速度,…

UE5 C++(十三)— 创建Character,添加增强输入

文章目录 创建Character第三人称模板添加增强输入引用在脚本中实现移动、旋转 创建Character第三人称模板 创建MyCharacter C类 添加增强输入引用 在DEMO.Build.cs 脚本中添加增强输入模块 有个容易出错的点,这里的设置一定要正确 然后添加引用到C头文件中 …

ssm基于WEB的文学网的设计与实现+vue论文

基于WEB的文学网的设计与实现 摘要 如今,科学技术的力量越来越强大,通过结合较为成熟的计算机技术,促进了学校、医疗、商城等许多行业领域的发展。为了顺应时代的变化,各行业结合互联网、人工智能等技术,纷纷开展了管…

时间序列数据库选型: influxdb; netdiscover列出docker实例们的ip

influxdb influxdb: 有收费版本、有开源版本 docker run -itd --name influxdb-dev -p 8086:8086 influxdb #influxdb的web客户端(端口8003)被去掉了 #8006是web-service端口docker pull chronograf docker run -d -p 8888:8888 --name chronograf-dev chronografsudo netst…

【VRTK】【Unity】【VR开发】Linear Drives

课程配套学习项目源码资源下载 https://download.csdn.net/download/weixin_41697242/88485426?spm=1001.2014.3001.5503 【概述】 前面一篇讨论了角度运动机制,本篇讨论线性运动机制。和角度运动机制类似,线性运动机制提供了更为仿真的互动机制。也分为基于物理的和不基于…

DDPM之反向传播

反向过程:由噪声状态恢复到数据状态的过程这一过程可以用条件概率来描述 是在时间步 t−1 想要恢复的数据状态。 是在时间步 t 的当前噪声状态。条件概率 p 服从高斯分布: 条件概率 是模型根据当前噪声状态 xt​ 和时间步 t 估计的均值是估计的方差和是由…