本篇内容介绍了“javascript的let和const命令怎么使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
let命令
基本用法
我们都知道let命令是用来声明变量的,类似于var,但是通过let命令声明的变量只在所在代码块内有效。
let a = [];for (let i = 0;i < 10; i++ ) { a[i] = function () { console.log(i); }}a[5](); // 5
如上代码所示,使用的是let声明的i,那么这个变量仅在块级作用域内有效,即只在每轮循环内有效,所以每次循环的i其实都是一个新变量,所以最后输出了5。
如果使用了var去申明i,那么这个i是在全局范围内都有效的,函数数组里的i都会指向同一个i,导出最后输出的是最后一轮循环的i的值。
那就有了一个疑问,使用let声明的i如果每一轮都是一个新变量,那怎么知道上一轮循环的值然后计算出本轮的值?
这是因为JavaScript引擎内部会记住上一轮循环的值,初始化当次循环的i时,会在上一轮循环的基础上计算。
for循环还有一个特别的地方,就是设置循环变量的括号内是一个父作用域,而循环体内是一个单独的子作用域。
特性
不存在变量提升:
不存在变量提升我们应该都知道,在var命令中会发生“变量提升”,就是变量可以在声明之前使用,而值是undefined。这种是比较奇怪的现象,因为他都还没声明怎么就可以使用呢?
所以。let命令改变了这种语法,通过let声明的变量一定要在变量声明后才能用,不然就会报错。
console.log(b) // undefinedconsole.log(a) // 报错ReferenceErrorlet a = 2;var b = 1;
暂时性死区
只要块级作用域内存在Let命令,那么这个let声明的变量就绑定了这个区域,不会受到外部的影响。
var num = 1;if(true) { num = 2; // 报错,ReferenceError let num;}
如上面代码所示,if代码块内想要修改的是if外部的num,但是if内部通过let声明了一个num但为赋值,所以导致了通过let声明的num绑定了这个块级作用域(即if内部这个块级作用域),所以不会受到外部的num影响,所以对num赋值会报错。
ES6明确规定了,如果在区块内存在let和const命令,那么这个区块对这些命令声明的变量从一开始就形成封闭的作用域,只要在声明之前就使用这些变量,就会报做。也称暂时性死区(temporal dead zone,简称TDZ)
当然,这也造成了typeof变得不安全了,因为如果一个变量没有声明就使用typeof不会报错,会返回一个undefined,但是现在不成立了,因为会报错ReferenceError。
function bar(x = y, y = 2) { return[x,y] }bar() // 报错
如上代码所示,调用bar函数会报错,因为参数x的默认值等于另一个参数y,但是x在声明的时候y还没有声明,属于死区
。
总之,只要进入当前作用域,所要使用的变量就已经存在,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。
其实let和const是存在变量提升的,但是由于暂时性死区的关系,变量已经存在了,但是不可获取,要等到声明变量的时候才可以获取和使用。
不允许重复声明
let不允许在校内共同作用域内重复声明同一个变量,这个就不用说了大家都知道。
let a = 1;let a = 2; // 报错
const
我们都知道const声明一个只读的常量。修改这个值就会报错。但是实际上保证的不是变量的值不能改动,而是变量指向的那个内存地址不能改动。
对于简单数据类型来说,值就是保存在变量指向的内存地址中,因此等同于常量。
而对于复合类型的数据,变量指向的内存地址保存的是一个指针,const只保证指针是固定,不保证内部的结构是不是可变的。
// 给对象添加一个属性 const foo = {} foo.name = 123 console.log(foo.name) // 123 // 将foo指向另一个对象,就会报错 foo = {} // 报错。
如果想要将对象冻结,可以使用Object.freeze
const foo = Object.freeze({});
特性
只在声明所在的块级作用域内有效。
const声明的常量不会提升,同样存在暂时性死区,只能在声明后使用。
不可重复声明。
补充——块级作用域
函数能不能在块级作用域中声明呢?
ES5中是规定函数只能在顶级作用域和函数作用域之中声明,不能在块级作用域声明。
ES6中引入了块级作用域,明确允许在块级作用域之中声明函数。而且。函数声明的语句的行为类似于let,在块级作用域之外不可引用。
function f() { console.log('I am outside!')}(function() { if(false) { function f() { console.log('I am inside') } }}f();}())
上面的代码,在es5中运行时会得到I am inside!
,因为if内部的f函数会被提升到函数头部。
但是在ES6环境则会报错,为什么呢?
因为游览器的实现有自己的方式:
允许在块级作用域内声明函数
函数声明类似于var,会提升到全局作用域或函数作用域的头部
函数声明还会提升到所在的块级作用域的头部
所以上述代码实际在ES6的游览器中会生成这样的代码:
function f() { console.log("I am outside!"); } (function () { var f = undefined; if (false) { function f() { console.log("I am inside"); } } })();
因此,应该避免在块级作用域内声明函数,如果确定需要写成函数表达式的形式,而不是函数声明语句。
“javascript的let和const命令怎么使用”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!