ES6——let/const/var、参数增强(...+解构)、箭头函数、模板字符串、for of

本文详细介绍了ES6中的let关键字,包括其特点、块级作用域以及与var的区别。接着讲解了参数增强,如参数默认值、剩余参数和打散数组的用法。此外,还深入探讨了箭头函数的语法简化及this的处理。最后,提到了模板字符串、for...of循环和解构赋值的概念及其应用。

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

 ECMA  ->  ECMAScript  ->  ES
            标准规范
 ES6:  js的第6套标准规范

一、 let

1. let底层原理

在底层自动转换为匿名函数自调用,且变量名=>_变量名

 let a = 100;
 👇
 (function(){
    var _a = 100;
 })()

接下来以var/let/const对比来讲解let的特性:

1.2 var let const三个区别

a. 变量提升

var声明的变量存在提升, 可在声明前调用(undefined
letconst不存在变量提升,有暂时性死区,等到声明以后才能使用该变量

console.log(a) // undefined
var a = 10

console.log(b) // 报错
let b = 10

console.log(c) // 报错
const c = 10

b. 块级作用域

大括号之间的语句块就是一个块级作用域,例如:if、else、while、do-while、for…

var无块级作用域
letconst有块级作用域

{
	var a = 20
	let b = 20
	const c = 20
}
console.log(a, b, c) // 20, 报错, 报错

c. 重复声明

var可以重复声明同一个变量
letconst同一个作用域下不允许重复声明同一个变量

d. 修改变量

varlet可以
const声明时必须赋值不允许重新赋值(引用地址)

总结: 能用const尽量使用const,次之let,避免使用var

二、参数增强

2.1 参数默认值(default)

形参变量有默认值可用,不至于是undefined

示例:

function fn(a, b, c=0) {
	console.log(a, b, c);
}

fn(1, 2, 3);
fn(1, 2); //1, 2, 0
fn(10000);//NaN

旧js版本兼容写法

function 函数名(形参1=默认值1, ...) {
  形参1 === undefined && (形参1=默认值); 
}

2.2 解构

将一个大的对象或数组中的个别成员提取出来单独使用.

2.2.1 数组解构

从数组中提取出个别值,单独使用,下标对下标,自动赋值

var [变量1, 变量2] = 数组

变量1 = 数组[0]
变量2 = 数组[1]

示例:

var arr = [
    {pid:1, pname:'yaya'},
    {pid:2, pname:'feifei'},
    {pid:3, pname:'yuanyuan'}
]
// 取出数组第一个和第二个对象
var [p1,p2] = arr;
//    0  1
console.log(p1); // {pid:1, pname:'yaya'},
console.log(p2); // {pid:2, pname:'feifei'},

//取出数组第一个和第三个对象
var [p1, , p3] = arr;
//   0      2
console.log(p1);
console.log(p3); // {pid:3, pname:'yuanyuan'}

2.2.2 对象解构

从对象中提取出个别成员(属性或方法),单独使用

var {属性名1:变量1,属性名2:变量2}=对象

es6简写: (属性名和变量名相等)

var {属性名1,属性名2}=对象

示例:

var db = {
   name: erya,
   port:3306,
}
var {name:name, port:port} = db;
// ES6简写:
var {name, login} = db;

console.log(name, login); // erya, 3306

2.3 剩余参数(rest) …

ES6箭头函数中碰到参数个数不确定的情况,都要用剩余参数语法来代替arguments
(arguments箭头函数不能使用)

优点:

  1. 支持箭头函数
  2. 生成的数组是纯正的数组类型,可以使用数组所有函数

数组拓展运算符

a. 转换为参数序列
示例一:
...在调用函数时是"打散":将数组打散为多个元素
...在定义函数时是"收集"

var add=(...arr)=>{
    return arr.reduce((x,y)=>x+y, 0);
}
const arr1=[1,2,3]
const arr2=[1,2,3,4,5]

add(...arr1) //6
add(...arr2);//15

示例二:...+解构

function cal(name,...arr){...}
cal("eyra",1,2,3); // name: erya, arr=[1,2,3]
cal("user",1,2,3,4); // name: user, arr=[1,2,3,4]

b. 展开数组
每次只能展开一层数组

var arr = [1, [2,3,4], 5]
console.log(...arr) // 1 [2,3,4] 5

c.复制数组:

var arr = [1,2];
var arr2=arr.slice();
👇
var arr2=[..arr]

d. 合并数组

var arr1 = [1,2];
var arr2 = [3,4];
var arr3=[].concat(arr1,arr2)
👇
var arr3=[..arr1, ...arr2] // [1,2,3,4]

e. 字符串转数组

[...'erya'] // ['e', 'r', 'y', 'a']

对象拓展运算符

a. 浅克隆对象

var obj2 = {...obj1};

b.合并两个对象

var obj3=Object.assign({},obj1,obj2);
👇
var obj3={...obj1, ...obj2} 
// 将obj1和obj2打散后,所有的属性,都放入第一个参数空对象中返回

三、箭头函数

3.1 简化语法规定

  1. 去掉匿名函数的function,小括号和大括号之间使用箭头()=>{ }
    ex: arr.sort( /*function */(a,b)=>{ return a-b; } )

  2. 箭头函数的函数体中只有一行代码,可以省略{}
    如果只有一行代码且是return形式,必须省略{}return
    arr.sort( (a,b)=>{return a-b} )

    arr.sort( (a,b)=>a-b )

  3. 如果只有一个形参,可以省略()
    arr.map( (elem)=>{return elem} )

    arr.map( elem=>elem )

示例:用箭头函数求三个数的平均值

//方法一
var pingjun=(a,b,c)=> {
    return (a+b+c)/3;
};
//方法二
var pingjun= (a,b,c)=> (a+b+c)/3;

3.2 箭头函数中的this

箭头函数没有属于自己的this,它的this是捕获所在上下文的this值。

如果希望函数内的this与函数外的this保持一致就可以改为箭头函数

对象中的方法不能改为箭头函数!
ES6中为对象的方法定义提供了一种专门的不带function的简写

var 对象名={
 属性名: 属性值, 
 方法名(){ ...  this.属性名 ... }
}

既不带:function,又不要加=>。
省略了function,又不等同于箭头函数,不会影响内部的this!

3.2.1 示例

原生bind()方法和箭头函数方法将函数内的this改为函数外的this

var erya = {
	sname:"erya",
	friends:["yaya","yuanyuan"],
	
	//原生写法:
	intr1:function(){
	    // erya调用,所以this->erya
	    this.friends.forEach(
	      function(ele) {
	        console.log(`${this.sname}的朋友是${ele}`);
	      }.bind(this)//绑定intr1作用域中的this
	    )
	},
	
	// intr:function(){简写intr() 既省略了function,但是又不等同于箭头函数,不会影响内部的this!
	intr() {
	  this.friends.forEach(
	  	// 箭头函数:可让函数内的this与函数外的this保持一致!
	    (ele)=>{
	      console.log(`${this.sname}的朋友是${ele}`);
	    }
	  )
	}
}
erya.intr1();
erya.intr();

3.2.2 图解

①在erya对象中,intr方法有一个作用域,且’erya’调用了intr方法,所以intr的作用域中this->erya。
intr方法中还有一个回调函数,它也有一块作用域
在这里插入图片描述

②在回调函数作用域中this因自身无this,所以找到window.sname,window中sname找不到,所以返回undefined
在这里插入图片描述
解决方法一:使用bind()绑定this
.bind(this),将intr中的’this->erya’传进来
在这里插入图片描述
解决方法二:使用箭头函数
箭头函数相当于将回调函数的作用域推倒
在这里插入图片描述

3.2.3 不支持new箭头函数

箭头函数没有prototype,也没有自己的this指向,不支持使用arguments 参数,所以不能new一个箭头函数。

new 操作符的实现步骤如下:
new运作的图解:JavaScript——this+面向对象(封装)以及new如何运作?

i. 创建一个新的空对象等待
ii.让新创建的对象自动继承构造函数的原型对象(将对象的__proto__属性指向构造函数的prototype属性)
iii. 将构造函数中的this->new刚创建的新对象
iv. 返回新对象的地址,保存到=左边的变量里。

上面的第ii、iii步,箭头函数都是没有办法执行的。

四、模板字符串

解决了字符串的拼接问题

   \` 模板字符串 ${JS表达式} \`

反引号(`)标识,它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。

// 普通字符串
console.log(`In JavaScript '\n' is a line-feed.`)
 
// 多行字符串
console.log(`In JavaScript this is
not legal.`)

var name = "ERYA", time = "tomorrow";
console.log(`
Hello ${name}, 
how are you ${time}?
`);

在这里插入图片描述

五、for of

遍历数字下标的数组或类数组对象

a. 普通for循环:
1). 优点: 既可遍历索引数组,又可以遍历类数组对象(arguments)
2). 缺点: 没有可简化的空间

b. forEach:
1). 优点: 可以配合ES6的箭头函数
2). 缺点: 无法用于遍历类数组对象

只要遍历数字下标的东西,都可用for of代替通for循环和forEach

  for(var 变量  of  索引数组/类数组对象){
    //of会依次取出数组或类数组对象中每个属性值
    //自动保存of前的变量中
  }

缺点:
a. 无法获得下标位置i,只能获得元素值
b. 无法控制遍历的顺序或步调(不能倒序等)

for of 和 for in 和 forEach()

Column 1Column 2普通forforEachfor offor in
数字下标索引数组×
数字下标类数组对象××
自定义下标关联数组×××
自定义下标对象×××
### 使用 `let` 关键字的上下文 在 HTML 中本身并不直接支持 `let` 关键字,因为 `let` 是 JavaScript 的一部分。然而,在嵌入到 HTML 文件中的 `<script>` 标签或者通过外部脚本文件加载时,可以使用 `let` 来声明变量。 #### 特性和行为 `let` 是 ES6(ECMAScript 2015)引入的一种新的变量声明方式,用于替代传统的 `var` 声明方法。它具有块级作用域(block scope),这意味着它的可见范围仅限于其所在的 `{}` 花括号内部[^4]。这使得代码更加安全和可预测,因为它不会像 `var` 那样提升(hoisting)并污染全局命名空间。 以下是几个关于 `let` 的重要特性: - **块级作用域**: 变量只在其定义的块内有效。 - **不可重复声明**: 同一作用域下再次声明相同名称的变量会抛出错误。 - **无变量提升**: 尽管存在暂时性死区(TDZ),但在初始化之前访问该变量会导致 ReferenceError。 #### 示例代码 下面是一些具体的例子来展示如何正确地使用 `let`: ```javascript // 块级作用域的例子 if (true) { let message = "Hello"; // 这里的message只能在这个花括号范围内被访问 } console.log(message); // 抛出ReferenceError: message is not defined function testBlockScope() { var i = 10; if(i === 10){ let j = 20; // 定义了一个局部变量j console.log(j); // 输出20 } // 下面这一行如果取消注释则会产生错误 // console.log(j); } testBlockScope(); // 循环内的迭代器示例 for(let k=0;k<3;k++){ setTimeout(function(){ console.log(k); },k*1000); } /* 上述循环每次都会创建一个新的绑定给setTimeout函数调用, 因此最终输出将是依次打印0,1,2而不是三个3 */ ``` #### 注意事项 尽管 `let` 提供了许多优势,但也需要注意一些潜在陷阱。例如,在某些情况下可能会意外覆盖父作用域中的同名变量。此外,由于它是较新标准的一部分,所以在非常老旧浏览器上可能不兼容。 ### 结论 总之,为了编写更清晰、维护更容易以及减少副作用风险较高的程序,请优先考虑采用 `let` 或者 const 替代旧式的 var 。这样不仅可以提高代码质量还能增强开发体验.
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你脸上有BUG

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值