es6新增语法特性,增强了JavaScript的功能和性能
ES6 提供了 let 和 const 来定义变量和常量
- 1.let 声明的变量具有块级作用域,这意味着它们只能在包含它们的代码块内访问。如果尝试在块级作用域之外访问 let 变量,将会抛出异常。
- 2.const 用于定义常量,一旦被赋值,其值就不能改变。常量的赋值必须在声明时完成。
注意:复杂数据类型,如数组和对象,const只是指向该变量的存储地址,若修改复杂数据类型里的值是可以操作的。例如数组push操作,修改arr[0]=1,但不可对整个数组重新赋值
如何破解?
使用 Object.freeze(obj) 这样可以冻结obj的一层属性不被修改,但是复合下层属性就无法冻结了。可递归处理每层,都冻结,就会将obj彻底冻结。
// freeze只能冻结当前层
function deepFreeze(obj) {
Object.freeze(obj)
(Object.key(obj) || []).forEach(key => {
if(typeof obj[key] === 'object') {
deepFreeze(obj[key])
}
})
}
问题:var 和 let 的区别?
1、var声明的变量往往会越域;let声明的变量有严格局部作用域
{
var a = 1;
let b = 2;
}
console.log(a) // 1
console.log(b) // Uncaught ReferenceError: b is not defined
2、var 可以声明多次;let只能声明一次
var m = 1;
var m = 2;
let n = 1;
let n = 2;
console.log(m) //2
console.log(n) //Uncaught SyntaxError: Identifier 'n' has already been declared
3、var会变量提升;let不存在变量提升
console.log(x); // undefined
var x = 10;
console.log(y); // Uncaught ReferenceError: Cannot access 'y' before initialization
let y = 12;
解构赋值
- ES6 允许从数组或对象中提取值,并将这些值分配给变量。这种语法使得在交换变量值或对象属性时更加简洁和易于理解。
1. 数组解构:
let arr = [1, 2, 3];
let [a, b, c] = arr;
console.log(a, b, c) //1,2,3
2. 对象解构:
const person = {
name: "qiyue",
age: 23,
language: ['java', 'js', 'css']
}
//从person里解析出name的值在赋值给abc,可以直接写name,也可以用形参abc接收代表它
const { name:abc, age, language } = person
console.log(abc, age, language) //qiyue 23 (3) ["java", "js", "css"]
箭头函数
- 箭头函数是一种定义函数的新方式,它们具有一些独特的特性,如不绑定 this 关键字,以及更简洁的语法。箭头函数特别适用于需要返回一个表达式的场合。
// 以前
var sum = function (a, b) {
c = a + b
return c
}
console.log(sum(2, 3)) // 5
// 箭头函数
var sum2 = (a, b) => a + b;
console.log(sum2(2, 4)) // 6
函数优化,参数默认值&剩余参数/不定参数
-
函数默认值:直接给参数写上默认值,没传就会自动使用默认值
function add(a, b = 1) {
return a + b;
}
console.log(add(10)) //11
- 剩余参数允许将一个不定数量的参数表示为一个数组,这在处理可变参数列表时非常有用。
function fun(...params) {
console.log(params)
console.log(params.length)
}
fun(1, 2, 3, 4) // [1,2,3,4] 4
对象优化
1. es6 给对象新增的方法:
-
key(obj):获取对象的所有key形成的数组
-
value(obj):获取对象的所有value形成的数组
-
entries(obj):获取对象所有的key和value形成的二维数组
const person = {
name: "qiyue",
age: 23,
language: ["java", "js", "css"]
}
console.log(Object.keys(person)) //["name","age","language"]
console.log(Object.values(person)) // ["qiyue",23,Array(3)]
console.log(Object.entries(person)) //[Array(2),Array(2),Array(2)]
2. Object.assign方法的第一个参数是目标对象,后面的参数都是源对象;将源对象的属性赋值到目标对象中,注意相同参数会覆盖,最后一个的值会成为最新值。
const target = { a: 1 }
const source1 = { b: 2 }
const source2 = { c: 3, a: 4 }
Object.assign(target, source1, source2);
console.log(target) //{a: 4, b: 2, c: 3}
3. 声明对象简写
// 以前
const name = 'zhang'
const age = 18
// 将属性值name,age分别赋给person对象的name,age,后面是属性值
const person = { name: name, age: age }
console.log(person) //{name: "zhang", age: 18}
// es6:属性名和属性值变量名一样,可以省略
const person2 = {name,age}
console.log(person2) //{name: "zhang", age: 18}
4. 对象的函数属性简写
let person3 = {
name: "zhang",
//以前
eat: function (food) {
console.log(this.name + "在吃" + food);
},
//箭头函数中this不能使用,用对象.属性
eat2: food => console.log(person3.name + "在吃" + food),
eat3(food) {
console.log(this.name + "在吃" + food)
}
}
person3.eat("苹果") //zhang在吃苹果
person3.eat2("香蕉") // zhang在吃香蕉
person3.eat3("西瓜") //zhang在吃西瓜
扩展运算
- 扩展运算符可以将数组或对象转换为用逗号分隔的参数序列,这在函数调用或对象字面量中传递多个参数时非常有用。扩展运算符(...)用于取出参数对象所有可遍历属性然后拷贝到当前对象。
//拷贝对象(深拷贝)
let p1 = { name: "zhang", age: 23 }
let obj = { ...p1 }
console.log(obj)//{name: "zhang", age: 23}
//合并对象
let age1 = { age: 24 }
let name1 = { name: "zhang" }
let p2 = {}
p2 = { ...age1, ...name1 }
console.log(p2) //{age: 24, name: "zhang"}
//如果p2中原本有name,age属性会被覆盖
字符串模版&字符串扩展
- 模板字符串允许在字符串中嵌入表达式,并且可以换行,换行会显示换行符
- 在``内部可使用 ${} 将变量包裹在花括号内,拼接字符串
let name = 'zhang'
let str = `my name is ${name}`
console.log(str) // my name is zhang
换行展示如下
- 字符串扩展
let str = "hello.vue";
console.log(str.startsWith("hello")) //true
console.log(str.endsWith("vue")) //true
console.log(str.includes("e")) //true
console.log(str.includes("hello")) //true
map & set & reduce
- ES6 引入了 Map 数据结构,用于存储键值对,其中键可以是任何类型的数据。
数组map():接收一个函数,将原数组中的所有元素用这个函数处理后放入新数组返回
let arr = ["1", "3", "4", "23"]
arr = arr.map(item => item * 2)
console.log(arr) //[2, 6, 8, 46]
-
reduce
reduce():为数组中的每一个元素依次执行回调函数,不包括数组中被删除或未被赋值的元素
语法:arr.reduce(callbace,[initialValue])
callback(执行数组中每个值的函数,包含四个参数)
previousValue(上一次调用回调返回的值,或者是提供的初始值(initialValue))
currentValue(数组中当前被处理的元素)、
index(当前元素在数组中的索引)
array(调用reduce的数组)
initialValue(作为第一次调用callback的第一个参数)
let arr1 = [2, 40, -10, 6]
let result = arr1.reduce((a, b) => {
return a + b
}, 10)
console.log(result)//48
-
Set 是一种类似于数组的数据结构,但成员必须是唯一的。
Set 和 Map 主要的应用场景在于 数据重组 和 数据储存。
Set 是一种叫做集合的数据结构,Map 是一种叫做字典的数据结构。
集合 与 字典 的区别:
共同点:集合、字典 可以储存不重复的值
不同点:集合 是以 [value, value]的形式储存元素,字典 是以 [key, value] 的形式储存
操作方法:
add(value):新增,相当于 array里的push。
delete(value):存在即删除集合中value。
has(value):判断集合中是否存在 value。
clear():清空集合。
const s = new Set()
let arr = [1,2,3,4,3,2,1]
arr.forEach(x => s.add(x))
console.log(arr)
for(let i of s) {
console.log(i) // 1 2 3 4
}
// 去重数组的重复对象
let arr1 =[1,2,3,2,1,1]
let arr2 = [...new Set(arr)] // [1, 2,3]
console.log(arr2)
Symbol
- ES6 提供了 Symbol 类型的原始数据类型,用于创建独一无二的值,这在处理对象属性名或用于数据共享时非常有用
Symbol是ES6中引入的一种新的基本数据类型,用于表示一个独一无二的值。它是JavaScript中的第七种数据类型,与undefined、null、Number(数值)、String(字符串)、Boolean(布尔值)、Object(对象)并列。
创建一个Symbol值:
const a = Symbol();
console.log(a); // Symbol()
const b = Symbol()
console.log(a === b) // false
console.log(typeof(a) === 'symbol') // true
使用Symbol函数可以生成一个Symbol类型的值,但是你不能在调用Symbol时使用new关键字,因为Symbol是基本数据类型,而不是对象,使用Symbol()创建一个Symbol类型的值并赋值给a变量后,将得到一个在内存中独一无二的值。现在除了通过变量a,任何人在任何作用域内都无法重新创建出这个值。
实际上,a变量拿到了内存中某块内存的唯一引用(这里所说的引用,其实就是该内存的地址)。如果不借助a变量,就不可能再得到这个地址。
es6语法详解:模块化
什么是模块化:模块化就是把代码进行拆分,方便重复利用。类似Java中的导包,要使用一个包,必须先导包。二Js中没有包的概念,换来的就是模块
模块的功能主要有两个命令构成:export和import
export命令用于规定模块的对外接口,export不仅可以导出对象,一切js变量都可以导出。比如:基本类型变量、函数、数组、对象
import命令用于导入其他模块提供的功能