ES6之块级作用域及let和const用法

一 、ES6-块级作用域

1、作用域的含义

javascript中的作用域说的是变量的可访问性和可见性。也就是整个程序过程中哪些部分可以访问这个变量,即变量或者是函数起作用的区域。

2、作用域的类型

javascript中有三种作用域:

  • 1、全局作用域
  • 2、函数作用域
  • 3、块级作用域
1、全局作用域

全局作用域:在script标签内,在函数外的区域。在全局作用域内定义的变量是全局变量,全局变量在任何地方都能访问到。

var greeting = "hello world"
function greet () {
	console.log(greeting)
}
greet() // 打印'hello world'
2、函数作用域

函数作用域也叫局部作用域,在js里面,只有函数才能形成的作用域。在函数内部定义的变量,只有在函数内部才能访问,不能在函数以外去访问。

function greet () {
	var greeting = 'hello world';
	console.log(greeting)
}
greet() // hello world
console.log(greeting) // 报错:Uncaught ReferenceError: greeting is not defined
3、块级作用域

ES6 引入了let 和 const 关键字,和var 关键字不同,在大括号中使用let 和 const 声明的变量存在于块级作用域中。在大括号之外不能访问这些变量。

{
	let greeting = 'hello world'
	var lang = 'English'
	console.log(greeting)
}
console.log(lang) // English
console.log(greeting) // 报错:Uncaught ReferenceError: greeting is not defined

作用域嵌套
像函数可以在一个函数内部声明另一个函数,作用域也可以嵌套在另一个作用域中。

var name = 'Peter'
function greet() {
	var greeting = 'hello'
	{
		let lang = 'English'
		console.log(`${lang}: ${greeting} ${name}`)
	}
}
greet ()

在这里有三层作用域,首先第一层是块级作用域,第二层是函数作用域,第三层作用域是全局作用域。

词法作用域
词法作用域就是在你写代码时将变量和块作用域写在哪里来决定,也就是词法作用域是静态的作用域,在你书写代码时就确定了

let number = 42
function printNumber() {
	console.log(number)
}
function log() {
	let number = 54
	printNumer()
}
log() // 42

3、作用域链

当在Javascript中使用一个变量的时候,首先Javascript引擎会尝试在当前作用域下去寻找该变量,如果没有找到,再到它的上层作用域寻找,以此类推直到找到该变量。如果找到全局作用域中仍然没有找到该变量,它就会报错。

let foo = 'foo'
function bar () {
	let bar = 'bar'
	console.log(bar) // bar
	console.log(foo) // foo
	number = 42
	console.log(number) // 42
}
bar()

二、let 与 const 用法

let 用来声明变量,所声明的变量只能在let命令所在的代码块内有效
const 用来声明常量,就是指针不可以改变的变量,它所声明的常量也只能在const命令所在的代码块中生效。

1、let 用法

  • let 声明的变量只在变量声明时所在的代码块有效
{
	let a = 10;
	var b = 1;
}
a // ReferenceError: a is not defined.
b // 1
  • 不存在变量提升现象
    var 命令会发生‘变量提升’现象 ,即变量可以在声明之前使用,值为underfined;但let所声明的变量一定要在声明后使用,否则报错
// var 
console.log(foo) // underfined
var foo = 2
// let
console.log(bar) // 报错
let bar = 2
  • 暂时性死区
    在代码块内,使用let命令声明变量之前,该变量都是不可用的。这种语法称为‘暂时性死区(TDZ)’
if (true) {
	// TDZ开始
	tmp = 'abc'
	console.log(tmp) // ReferenceError
	let tmp; // TDZ结束
	console.log(tmp) // underfined
	tmp = 123
	console.log(tmp) // 123
}

暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在,但是不可获取,只有等到声明变量的哪一行代码出现,才可以获取和使用该变量

  • let 不允许在同一作用域重复声明变量
function func () {
	let a = 10;
	var a = 1;
} // 报错
function func () {
	let a = 10;
	let a = 20;
} // 报错

同时,也不能在函数内部重新声明参数

function func (arg) {
	let arg // 报错
}
function func(arg) {
	{
		let arg; // 报错
	}
}
  • 关于for循环

for 循环中存在块级作用域,在循环中,我们使用var声明一个变量,循环结束后,我们希望这个变量被销毁,但是var 声明的变量具有变量提升,所以我们在循环结束后,这个变量还是存在全局作用域中,会污染我们的全局作用域。这个时候我们可以使用let 来声明循环中变量,就可以解决这个问题

// 使用var
for (var i = 0; i < 10; i++) {
 // ....
}
console.log(i) // 10
// 使用let
for (let i = 0; i < 10; i++) {
// ....
}
console.log(i) // ReferenceErroe: i is not defined

注意:for 循环设置循环变量的那一部分是一个父作用域,而循环体内部是一个单独的子作用域。

for (let i = 0; i < 3; i++) {
	let i = 'abc'
	console.log(i)
}
// abc
// abc
// abc

2、const

  • const 声明一个只读的常量。一旦声明,常量的值就不会改变。
const PI = =3.1415;
PI = 3; // TypeError: Assignment to constant variable
  • const 一旦声明变量,就必须立即初始化,只声明不赋值,就会报错。
const foo; // // SyntaxError: Missing initializer in const declaration
  • const的作用域与let命令相同:只在声明所在的块级作用域内有效。
if (true) {
  const MAX = 5;
}
MAX // Uncaught ReferenceError: MAX is not defined
  • const命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。
if (true) {
  console.log(MAX); // ReferenceError
  const MAX = 5;
}
  • const声明的常量,也与let一样在同一作用域中不可重复声明。
var message = "Hello!";
let age = 25;

// 以下两行都会报错
const message = "Goodbye!";
const age = 30;
  • const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。
const foo = {};

// 为 foo 添加一个属性,可以成功
foo.prop = 123;
foo.prop // 123

// 将 foo 指向另一个对象,就会报错
foo = {}; // TypeError: "foo" is read-only

注意:上面代码中,常量foo储存的是一个地址,这个地址指向一个对象。不可变的只是这个地址,即不能把foo指向另一个地址,但对象本身是可变的,所以依然可以为其添加新属性。

最后

如果文章中有错误,请务必指出,万分感谢。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值