ES6 新特性

本文详细介绍了ES6中的let和const关键字,包括它们的块级作用域、暂时性死区等特性,并通过实例展示了如何避免变量提升和循环变量污染。此外,还讲解了解构赋值在数组、对象和字符串中的应用,以及函数参数的解构赋值和扩展运算符的使用。最后,提到了模板字符串的便利性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近复习了es6 ,写写博客整理一下相关知识

let 和 const 关键字

let

ES6 新增了let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。
使用 let 声明的变量有以下几个特点:

  1. 不允许重复声明;
  2. 块儿级作用域(局部变量);
  3. 不存在变量提升;
  4. 不影响作用域链;
  5. 暂时性死区
//使用let 关键字声明的变量不允许重复声明
//var 声明变量可以重复声明
let a
let a = 12  // a已经声明,此处为错误用法!

// var 可以在代码块之外读取变量
//使用let关键字声明的变量具有块级作用域,声明的变量只在所处于的块级有效
{
    let fruit='apple'
}
console.log(fruit) //error

//let 不存在变量提升,var 存在变量提升
console.log(a);  //a is not defined
let a = 20;  

//不影响作用域链就是:上级代码块中的局部变量下级可用
{
	let  p=1
	function fn(){
		console.log(p)  // 这里是可以使用的
	}
	fn() 
}
//从作用域链的结构可以看出,函数在执行的过程中,先从自己内部寻找变量,如果找不到,再从创建当前函数所在的作用域去找,从此往上,也就是向上一级找

//暂时性死区
var tmp = 10;
if (true) {
	console.log(tmp);    //tmp is not defined
	let tmp = 20;
 }
/*
ES6 明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。
上面代码中,存在全局变量tmp,但是块级作用域内let又声明了一个局部变量tmp,导致后者绑定这个块级作用域,所以在let声明变量前,对tmp赋值或者使用都会报错。
总之,在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。
*/

let 声明的变量存在块级作用域,由于这个特性,let可以用来防止循环变量变成全局变量

for(var i = 0; i<5;i++){
    setTimeout(()=>console.log(i),0) // 5 5 5 5 5
}

在for循环中使用var,因为var是全局变量,所以循环结束后值会被覆盖掉,setTimeout 是一个异步,所以它拿到的是循环结束后的i的值,因此会打印出五个5。

for(let i = 0; i<5;i++){
   setTimeout(()=>console.log(i),0)//0 1 2 3 4
}
//在每次执行循环体之前,JS 引擎会把 i 在循环体的上下文中重新声明及初始化一次。
//你也可以当成是声明了五个let块级作用域
{let i = 0}
{let i = 1}
{let i = 2}
{let i = 3}
{let i = 4}

const

const 关键字用来声明常量,const 声明有以下特点:

  1. 声明必须赋初始值,赋值之后不允许修改;
  2. 标识符一般为大写(习惯);
  3. 不允许重复声明;
  4. 块儿级作用域(局部变量);
// const声明常量,一经声明,则不允许修改
//const声明的变量不得改变值,这意味着,const一旦声明变量,就必须立即初始化,不能留到以后赋值。
const fruit  // 未赋值,报错

//标识符一般为大写(习惯)
const FRUIT = "apple" 
console.log(FRUIT) // "apple" 

//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 BOOKS = ['三体', '海子的诗', '西游记']
let [san, hai, xi] = BOOKS
console.log(san) // '三体'
console.log(hai) // '海子的诗'
console.log(xi) // '西游记'
let [h, m] = BOOKS
console.log(h); // '三体'
console.log(m); // '海子的诗'

对象的解构赋值

const ZHANGSAN = {
    name: '张三',
    age: 23,
    gender: '男',
    speak: function () {
        console.log("Hello,I'm ZhangSan!")
    }
}

 let {name,age,gender,speak} = ZHANGSAN;
 console.log(name)  // '张三'
 console.log(age)  //   23 
 console.log(gender)  //  '男'
 console.log(speak)  //  function(){...}
 speak()             //  "Hello,I'm ZhangSan!"

//如果不使用方法的结构赋值,每次调用方法都要写
ZHANGSAN.speak()

console.log('只进行对象里面的方法解构赋值');
let {
    speak
} = ZHANGSAN;
console.log(speak) //[Function: speak]

//解构赋值的时候,变量名要与对象里面的属性名字相同
let {
    aaa
} = ZHANGSAN;
console.log(aaa); //undefined

对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
let {name,age,gender,speak} 这种解构其实是一种简写,所以在进行对象的解构赋值的时候,要注意变量名必须是对象里面存在的属性名
具体参考这篇文章
https://es6.ruanyifeng.com/#docs/destructuring

字符串的解构赋值

字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。

const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"

类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值。

let {length : len} = 'hello';
len // 5

函数参数的解构赋值

function add([x, y]){
 	 return x + y;
}
	
add([1, 2]); // 3

上面代码中,函数add的参数表面上是一个数组,但在传入参数的那一刻,数组参数就被解构成变量x和y。对于函数内部的代码来说,它们能感受到的参数就是x和y。
函数参数的解构也可以使用默认值:

function func({x,y=5}){
	console.log(x,y);
}
func({});   //undefined,5
func({x:1}) // 1,5 
func({x:1,y:2})  //1,2
foo()   // TypeError:Cannot read property 'x' of undefined

函数参数的默认值一般位置要靠后
上面的写法是为x,y 变量指定默认值,所以当没有给y 传递实参的时候,打印的y 就是5
下面的问一种写法是为函数的实参指定默认值

function move({x, y} = { x: 0, y: 0 }) {
  	return [x, y];
}
	
move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, undefined]
move({}); // [undefined, undefined]
move(); // [0, 0]

当调用move 方法,却没有传递实参的时候,默认给它传递一个参数为{ x: 0, y: 0 },所以move() 的打印结果为[0, 0];
并没有给x,y 变量指定默认值,所以第二种和第三种会打印出undefined

扩展运算符

扩展运算符… ,能将数组转换为逗号分隔的参数序列;
扩展运算符放在实参的位置,就是调用函数的时候去使用;

const arr = [1, 2, 3, 4, 5]

function fun() {
    console.log(arguments);
}
fun(arr) //[Arguments] { '0': [ 1, 2, 3, 4, 5 ] }
fun(...arr); //[Arguments] { '0': 1, '1': 2, '2': 3, '3': 4, '4': 5 }

应用

//扩展运算符可以用来拷贝数组,不过要注意的是这是一个浅拷贝。
const arr1 = [1, 2, 3]
const arr2 = [...arr1]
console.log(arr2);

//数组合并
const arr3 = [1, 2, 3];
const arr4 = [4, 5, 6];
//早期间我们可以使用concat方法
//const arr5=arr3.concat(arr4)

const arr5 = [...arr3, ...arr4];
console.log(arr5); // [ 1, 2, 3, 4, 5, 6 ]

模板字符串

使用一对反引号 声明的字符串,特性如下:

  1. 里面可以直接使用换行
let str = `<ul>
			<li>111</li>
			<li>222</li>
			<li>333</li>
		  </ul>`

2.变量拼接(替换/插入)
使用${变量名}定位插入的元素位置

let a = 20;
let str = `${a}的值为20`
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值