详解var、let、const关键词声明变量的区别,以及变量提升、块级作用域的认识等。

首先回顾一下JavaScript中var声明变量的基础知识:

• 在使用var关键词声明变量时,变量在函数外则是全局变量,有全局作用域,全局变量在页面关闭后销毁;变量在函数内则是局部变量,作用局部作用域(变量只能在该函数内有效,函数执行完将自动销毁)

• 我们使用var来创建变量,声明后未赋值的变量输出会提示 “undefined”。在方法函数外声明的变量未使用var ,会报错“x is not defined”;

• 在函数内未使用var声明的变量自动变为全局变量


开发背景(WHY)为什么要使用let、const关键词来创建变量或常量

•解决ES5使用var初始化变量时会出现的变量提升问题

•解决使用闭包时出错的问题

•解决使用计数的for循环变量时候会导致泄露为全局变量的问题,

•ES5只有全局作用域和函数作用域(对应var声明的全局变量和局部变量时),没有块级作用域(ES6中{}中的代码块)。同理只能在顶层作用域window中和函数中声明函数,不能在块级作用域中声明函数;


那么先来理解一下什么是变量提升特性,会导致的问题(比如内层变量覆盖外层变量)


•变量初始化时可以分为两步:使用关键词var声明变量,以及赋值。变量提升就是将声明变量这一步提升到该作用域的头部。注意函数声明也会类似var声明出现提升特效,函数声明提升在变量声明提升上面;

参考网址:https://blog.csdn.net/recoluan/article/details/79253223

实例01

console.log(foo);
console.log(foo2);
var foo=2;
let foo2=3;

//以上代码var声明变量后,相当于如下
// var foo;
// console.log(foo); //会提示‘undefined’
// foo=2;
// let不存在变量提升,会报错

实例02

var a="我在外面";
function func(){
console.log(a); //undefined
console.log(window.a); //我在外面
var a='我在里面';
console.log(a); //我在里面
}
//以上代码var声明变量后,相当于如下
// var a="我在外面";
// function func(){
// var a;
// console.log(a);
// console.log(window.a);
// a='我在里面';
// console.log(a);
// }

注意:在使用let、const命令声明的变量不具备变量提升效果;

    :函数声明提升会在变量声明提升上面

fuc2();
function fuc2(){
console.log(b); //undefined
}
var b=35;
//相当于
// function fuc2(){
// console.log(b);
// }
// var b;
// func2();
// b=35;


为什么需要块级作用域?

• 用来计数的循环变量泄露为全局变量,如下:

for (var i = 0; i < s.length; i++) {
console.log(s[i]); //会将字符串拆分为一个个的字符输出
}
console.log(i); // 5


• let和const是ES6新增特性,都可生成块级作用域(是指声明在花括号内的变量只在该区域内有效)。let用来声明变量,const用来声明常量(不可修改变量值,数组和对象除外);如果区块内存在let或const命令,这个区块对这些命令声明的变量会形成封闭的区域,该区域外不能被使用,且变量声明前使用变量会报错(又叫暂时性死区),更加严谨

var tmp = 123;
if (true) {
tmp = 'abc';
// ReferenceError,不能未声明前使用这就是暂时性死区
console.log(temp);
let tmp;
temp=666;
console.log(temp);
}


function bar(x = y, y = 2) {
return [x, y];
}
bar(); // 报错


块级作用域外不能访问该区块内的变量或者常量,子块级作用域可以访问父块级作用域的变量

{
const ss=99;
{
console.log(ss); //可以在子块内访问父块定义的常量
}
}
console.log(ss); //b不可以在块作用外访问let、const定义的变量或者常量

以上代码中通过将let替换var就可以修复各种bug,所以,let是更完美的var”。


其他的let、const和var的用法及注意点

• let和var的区别:let声明的变量只在其声明的块或子块中可用,而var声明的变量的作用域是整个封闭函数可用;

• let和const的特点:

① let和const关键词声明的变量不具备变量提升的特效(第二步提到了的),存在暂时性的死区,只能在声明的位置后使用,同一块级作用域中不能反复声明同一变量名(子块级可以重复声明父块级变量),var可以;

② let和const声明只在最靠近的一个块(花括号内)中有效;

③ 使用const声明常量时候大写,const在声明时必须赋值;

注意1: const声明的变量值并不是不能变的,而是变量指向的内存地址是不能变的,对于数值、字符串等简单类型的数据,值就保存在变量指向的内存地址上,因此等同于常量;但对于符合类型的数据(如数组和对象),变量指向的内存地址是一个指引,数据结构是否可变就不能控制了,所以将对象声明为常量必须非常小心;

const newArr=[23,43,22,66];
newArr[0]=888;
console.log(newArr); //[888, 43, 22, 66]

注意2:外层块作用域不可以访问块内层作用域,内层块作用域可以获取外层块作用域变量,子块可以重复定义外层块作用域变量。函数在块级作用域中声明是行为类似let,不能被作用域外访问,块中的函数声明存在变量提升,确实需要时候使用函数表达式的形式,而不是函数声明语句形式;

function f() { console.log('I am outside!'); }
(function () {
if (false) {
//函数提升后,这里重复声明了该匿名函数外的函数f,所以会覆盖外部函数
function f() { console.log('I am inside!'); }
}
f();
}());

注意3:  Let不允许在相同作用域中使用与其他let或const,重复声明同一个变量,所以不能在有参函数声明中重复声明函数参数,如function func(arg){let arg}会报错

var message = "Hello!";
let age = 25;
// 以下两行都会报错
const message = "Goodbye!";
const age = 30;


注意4: 在ES5中顶层对象(在浏览器指的是window对象),顶层对象属性和全局变量是等价的。属性也可以动态创建变量,顶层对象的属性可以被随处读写不利于模块化编程;而在ES6中,var命令和function命令声明的全局变量,依旧是顶层对象的属性;另一方面规定,let命令、const命令、class命令声明的全局变量,不属于顶层对象的属性。也就是说,从 ES6 开始,全局变量将逐步与顶层对象的属性脱钩。

var aaa=1;
console.log(window.aaa); //输出1
let bbb=2;
console.log(window.bbb ); //输出undefined



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

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

相关文章

腾讯视频如何设置热键

本文小编给大家带来的是腾讯视频相关的内容。腾讯视频有快捷键的功能&#xff0c;那怎么设置或更改呢?来看一下具体步骤吧! 1、首先&#xff0c;打开电脑里的腾讯视频&#xff0c;然后点击右上方的“菜单”键 2、点击后会弹出一个弹窗&#xff0c;点击“设置” 3、进入设置…

浏览器tab标签显示网站标志图标

对于不同的浏览器&#xff0c;方法是有差别的 1.对于IE或TT浏览器&#xff1a;把需要显示的16x16像素的ICO图标命名为favicon.ICO放置在网站根目录下&#xff0c;浏览器会自动检索 2.这大概是所有浏览器通用的在标签页加入指定图标的方法&#xff1a; 把favicon.ico图标放到网站…

如何使用腾讯视频小程序功能

很多人都使用腾讯视频&#xff0c;播放器家园网小编给大家分享一下如何下载腾讯视频里的视频_*腾讯视频&#xff5e;如何使用腾讯视频小程序功能呢相关内容。 腾讯视频&#xff5e;如何使用腾讯视频小程序功能呢? 首先找到手机软件&#xff0c;打开后按照下面的指示一步步完…

关于web前端性能优化总结

1、从DOM结构和标签上来优化使用语义化的标签&#xff0c;代码清晰简洁&#xff1b; 减少Dom节点&#xff0c;增加渲染速度&#xff1b; 使用W3C标准书写闭合小写的标签&#xff1b; 给图片和table指定宽高&#xff0c;避免缩放&#xff1b; 防止src和href值为空&#xff0c;当…

爱奇艺视频播放怎么开加速

很多人都使用爱奇艺&#xff0c;播放器家园网小编给大家分享一下爱奇艺下载电视剧怎么下载手机_爱奇艺视频播放什么开加速相关内容。爱奇艺视频播放什么开加速?爱奇艺视频播放的时候想要加速播放&#xff0c;那到底是什么整的呢&#xff0c;具体的设置操作步骤如下 1、点击爱…

关于提高网页加载速度个人学习以及经验总结

性能黄金法则&#xff1a; 记住&#xff1a;只有10% - 20%的最终用户时间花在了下载HTML文档上&#xff0c;其余的80%-90%时间花在下载页面中的所有组件&#xff08;js、css 、image 、flash&#xff09;进行的http请求上。根据上面的黄金法则&#xff0c;可以知道网页提速方式…

搜狐视频如何开启青少年模式

搜狐视频开启青少年模式可以避免孩子使用时造成的无意识消费&#xff0c;那么如何开启呢?下面给大家简单介绍一下 1、首先在手机桌面找到【搜狐视频】并点击进入 2、在【我的】页签点击右上角设置图标进入 3、点击【青少年模式】进入 4、点击【开启青少年模式】即可完成本…

VUE学习和开发中的注意点总结(一),便于回顾(不断完善补充。)

1、export 和export default 的区别&#xff1f; 在JavaScript ES6中&#xff0c;export与export default均可用于导出常量、函数、文件、模块等&#xff0c;你可以在其它文件或模块中通过import(常量 | 函数 | 文件 | 模块)名的方式&#xff0c;将其导入&#xff0c;以便能够对…

手机qq浏览器过滤广告设置教程

手机qq浏览器过滤广告设置教程 手机QQ浏览器怎么过滤广告?今天浏览器家园小编给大家分享的是如何屏蔽手机QQ浏览器广告?对这个感兴趣的小伙伴们就一起学习下吧&#xff0c;以下就是具体的内容。 手机QQ浏览器屏蔽广告方法 1.打开手机QQ浏览器&#xff0c;点击底栏【菜单】 …

绘制扇形的多种方式,包括border-radius、clip裁剪显示、canvas原点变换等方式的详细理解及demo

对clip的理解&#xff1a; clip是对使用了该样式的元素进行裁剪显示。使用方法是rect (top, right, bottom, left) 其中参数top代表显示的区域上边界离该元素顶部border-top相对距离&#xff0c;依此分别是右边界离该元素左侧border-left相对距离。参数top和left取值auto时候代…

QQ浏览器怎么设置为默认浏览器

怎么将qq浏览器安装成自己想要的默认浏览器呢&#xff0c;今天小编就教大家一个方法&#xff0c;通过简单的方式&#xff0c;将qq浏览器设置成默认浏览器&#xff0c;这样用户在操作的时候就会更加的方便&#xff0c;打开浏览器就可以使用qq浏览器的功能&#xff0c;那么到底要…

在VUE项目中使用SCSS ,对SCSS的理解和使用(简单明了)

首先要了解什么是CSS 预处理器&#xff1f; SCSS是一种CSS预处理语言定义了一种新的专门的编程语言&#xff0c;编译后形成正常的css文件&#xff0c;为css增加一些编程特性&#xff0c;无需考虑浏览器的兼容性&#xff08;完全兼容css3&#xff09;&#xff0c;让css更加简洁、…

如何解决360浏览器卡死的问题

我们在上网的时候&#xff0c;不可缺少的就是浏览器了&#xff0c;有一大部分人还是喜欢用360浏览器的。刚开始用360浏览器的时候感觉很不错&#xff0c;都都不知什么情况&#xff0c;老是无故崩溃&#xff0c;或者时常卡死&#xff0c;上网慢&#xff0c;播放视频插件响应失败…

前端windows下常用的CMD 命令归纳

前言&#xff1a;在vue项目开发或安装部署卸载时候经常会用到CMD命令操作&#xff0c;所以这里将常用到的cmd命令进行归纳。在运行框或cmd界面输入以下代码&#xff0c;回车键确定跳转对应的功能或界面shutdown 关机&#xff1b;mspaint 打开画图工具&a…

360浏览器图片放大镜如何关闭

360浏览器图片放大镜怎么关闭?360浏览器是一款功能强大的浏览器&#xff0c;在使用浏览器的时候&#xff0c;鼠标移动到图片那里&#xff0c;就会自动放大。有时候会很不方便&#xff0c;要怎么关闭呢&#xff0c;下面就给大家分享具体步骤。 打开工具&#xff0c;选择设置&a…

VUE中父子组件传参(简单明了)

父组件向子组件传递参数 child.vue如下 <template><div class"childClass"><h3>子组件内容</h3><p :class"num6?redclass:blueclass">当父组件内容传递给子组件时&#xff0c;该行变成红色</p><p>父组件向子…

360安全浏览器极速模式怎么设置

360安全浏览器极速模式怎么设置 在window操作系统电脑中最常做的事情就是浏览网页查找资料了&#xff0c;这就需要用到浏览器&#xff0c;而浏览器的种类五花八门。其中360浏览器使用率比高&#xff0c;其中有一个极速模式&#xff0c;可以快速浏览文章内容。如何设置360浏览器…

行内元素和块级元素的区别,为何img、input等行内元素可以设置宽高??(夯实基础)

我们习惯将html中元素分类为行内元素和块级元素&#xff0c;如下&#xff1a;常见块级元素有&#xff1a;html、body、div、header、footer、nav、section、aside、article、p、hr、h1~h6、ul、ol、dl、form、table、tbody、thead、tfoot、tr等&#xff1b;常见行内元素有&…

360浏览器是ie浏览器吗?有什么区别

核心提示&#xff1a;360浏览器是360公司开发的产品&#xff0c;它是基于IE浏览内核开发的。 360浏览器是ie浏览器吗?有什么区别 360浏览器不是ie浏览器。 360浏览器是360公司开发的产品&#xff0c;它是基于IE浏览内核开发的。 360浏览器与ie浏览器的区别 360安全浏览器…

VUE中 ref $refs 使用详解,扩展到$parent 、$children 的使用

$refs 的使用方法就是在元素或组件标签上添加ref属性指定一个引用信息&#xff0c;引用信息将会注册在父组件的$refs对象上&#xff0c;在js中使用$refs来指向DOM元素或组件实例&#xff1b; 应用一&#xff1a;在DOM元素上使用$refs可以迅速进行dom定位&#xff0c;类似于$(&q…