前端ES6+基础总结(上)
1.什么是ES6
ES6即ECMA Script, 是由ECMA国际标准化组织,制定的一项脚本语言的标准化规定。
ES6很多时候是一个泛指,指在ESMA Script 2015之后的版本。
2. let声明变量
ES6中新增的用于声明变量的关键字。
1.let 声明变量只在所处的块级有效
if (true) {
// let声明有块级作用域的概念 而var没有这方面的概念
let a = 0
var b = 0
}
console.log(b)// 0
console.log(a)//a is not defined(报错) 因为块级作用域外界无法访问
2.let 不存在变量的提升
console.log(a) //undefined
var a = 20
因为var在预编译时会将声明提前
最终编译为
var a
console.log(a)
a=0
所以打印是undefined
而下面的let不存在变量提升
console.log(b)//报错
let b = 20
3.暂时性死区
因为自己作用域的let无法提前,外部又访问不到,这就形成了暂时性死区。
var a= 123
if(true){
a=456 //因为自己的作用域中的let无法提前,外部又访问不到
let a //报错
}
3. const声明常量
作用:声明常量
常量:常量就是值(内存地址)不能变化的量
1.const常量赋值后,值不能更改
const p =3.14
p=100 //报错
2.当const 声明复杂类型时,可以修改其中的项,但不能给整个常量重新赋值,改变其内存地址
const arr = [100,200]
arr[0]=400,
arr[1]=[500]
console.log(arr) // 400,500
arr=[699,799]
console.log(arr)//报错
let 、const、var 的区别
var | let | const |
---|---|---|
函数级作用域 | 块级作用域 | 块级作用域 |
声明变量 | 声明变量 | 声明常量 |
变量提升 | 不存在变量提升 | 不存在变量提升 |
值可更改 | 值可更改 | 值不可改(复杂类型内存地址不可改) |
允许重复声明 | 不允许重复声明 | 不允许重复声明 |
4. 解构赋值
ES6中允许从数组或对象中提取值,按照对应位置,对变量赋值,这就是解构赋值。
1.数组结构赋值
const arr = ["沈腾", "贾玲", "关晓彤", "华晨宇"]
let {user1,user2,user3,user4,user5} =arr
//结构数值一一对应 结构不成功,则该值为undefined
console.log(user1) //沈腾
console.log(user2)//贾玲
console.log(user3)//关晓彤
console.log(user4)//华晨宇
console.log(user5)//undefined
2.对象解构赋值
let person={name:"憨八龟",age:38}
//对象结构赋值有两种方法
写法一: 直接使用
let {name,age}=person
console.log(name)//憨八龟
console.log(age)// 18
写法二:let {name:youName,age=youAge} =person
console.log(youName)//憨八龟
5. 模板字符串
ES6新增创建字符串的方式,使用反引号定义。
1.模板字符串通过${}可以解析变量
let name = `张三`
let say=`hello,${name}
,你好吗`
2.模板字符串中可以调用函数
3.模板字符串中可以换行
6.对象的自增强写法
1.对象的属性和值相同 则可以省略
let obj={
//name:name 可以简写为
name
}
2.方法简写
let obj ={
//fn:function(){}可以简写为
fn(){}
}
7. 箭头函数
ES6中定义函数的方式。
ES5定义函数的方式
function sum (num){
console.log(num)
}
ES6中定义函数的方式
//当参数只有一个时 可以省略小括号
//当函数体只有一句话 且代码结果就是返回值时,可以省略大括号
//函数体只有一行时,如果要return结果 则必须不写return
const sum =num=>console.log(num)
1.箭头函数不绑定this,其this指向函数定义位置上下文的this
2.不能作为构造函数 实例化对象
let person =(name){
person.name = name
}
let user = new person("憨八龟")
console.log(user) //报错
3.不能使用arguments函数
let fn(){
console.log(arguments) //报错
}
fn(1,2,3)
箭头函数的适用场景:
箭头函数适合与this无关的回调,如定时器,数组的方法回调等。
箭头函数不适合与this有关的回调,事件回调,对象的方法。
8. 函数的初始默认值
ES6中允许函数有默认初始值。
//与解构赋值搭配
function request({
name = "憨八龟",
age = 19
}) {
console.log(name) //忍者神龟
console.log(age) //18
}
request({
name: "忍者神龟"
})
9. rest参数
ES6 引入 rest 参数,用于获取函数的实参,用来代替 arguments,并转而用数组的方式输出,加强对数据的处理。
ES5
function content() {
console.log(arguments);//结果是一个对象
}
content(1, 2, 3, 4)
ES6
function content(a, b, ...args) {
console.log(args)//结果是一个数组[3,4]
}
content(1, 2, 3, 4)
10.扩展运算符
1.扩展运算符可以将对象或数组转为用逗号隔开的参数序列。
格式为:...要展开的对象或数组
let arr = [1,2,3]
console.log(...arr) //1 ,2 ,3
console.log(arr) //[1,2,3]
2.扩展运算符可以应用于合并数组
let arr =[1,2,3]
let arr2 = [4,5,6]
let arr3=[...arr,...arr2]
console.log(arr3) //1,2,3,4,5,6
3.将伪数组或可遍历的对象转换为真正的数组
let divs = document.getElementByName('div')
divs =[...divs]
11. Symbol数据类型
ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值。它是 JavaScript 语言的第七种数据类型,是一种类似于字符串的数据类型。
注意
- Symbol 的值是唯一的,用来解决命名冲突的问题
- Symbol 值不能与其他数据进行运算
- Symbol 定义 的 对象属 性 不能 使 用 for…in 循 环遍 历 ,但 是可 以 使 用 Reflect.ownKeys 来获取对象的所有键名+
1.创建symbol
let s1= symbol()
2.symbol函数可以接收一个字符串作为参数,
//该字符串表示对symbol实例的描述,主要用于区分
let s2=Symbol("user")
//可以转字符串
String(s2)或 S2.toString
//可以转布尔类型
!S2
3.作为属性名的 Symbol
//由于每一个 Symbol 值都是不相等的,这意味着 Symbol 值可以作为标识符,用于对象的属性名,就能保证不会出现同名的属性。这对于一个对象由多个模块构成的情况非常有用,能防止某一个键被不小心改写或覆盖。 --来自阮一峰老师ES6
let mySymbol = Symbol();
// 第一种写法
let a = {};
a[mySymbol] = 'Hello!';
// 第二种写法
let a = {
[mySymbol]: 'Hello!'
};
// 第三种写法
let a = {};
Object.defineProperty(a, mySymbol, { value: 'Hello!' });
//注意,Symbol 值作为对象属性名时,不能用点运算符。
// 以上写法都得到同样结果
a[mySymbol] // "Hello!"
4. symbol.for()全局注册方法
有时,我们希望重新使用同一个 Symbol 值,Symbol.for()
方法可以做到这一点。它接受一个字符串作为参数,然后搜索有没有以该参数作为名称的 Symbol 值。如果有,就返回这个 Symbol 值,否则就新建一个以该字符串为名称的 Symbol 值,并将其注册到全局。
Symbol()每调用一次 创建一个不同的Symbol对象
let arr1 = Symbol("arr")
let arr2 = Symbol("arr")
console.log(arr1 == arr2) //false
Symbol.from 全局注册,调用时现在全局找 全局有则使用 没有的话再创建Symbol对象
let arr3 = Symbol.for("arr")
let arr4 = Symbol.for("arr")
console.log(arr3 == arr4) //true
symbol很多情况下是对对象的扩展
let demo = {
name: "我是demo",
[Symbol("hi")]() {
console.log("你好吗")
},
[Symbol("superman")]() {
console.log("我是超人")
}
}
demo[Symbol("age")] = () => {
console.log("我今年199岁了")
}
console.log(demo)
效果图:
12.迭代器(for..of)
遍历器(Iterator)就是一种机制。它是一种接口,为各种不同的数据结构提 供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作。Iterator接口在JS指的是其属性Symbol(Symbol.iterator)。例如数组的Symbol(Symbol.iterator)属性在其原型链上。
注意: 需要自定义遍历数据的时候,要想到迭代器。
原生具备 iterator 接口的数据(可用 for of 遍历):
- Array
- Arguments
- map
- set
- String
- TypedArray
- NodeList
迭代器工作原理:
- 创建一个指针对象,指向当前数据结构的起始位置
- 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员
- 接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员
- 每调用 next 方法返回一个包含 value 和 done 属性的对象
自定义遍历数据,手动写迭代器
let obj = {
user: "管理员",
jurisdiction: ["增", "删", "改", "查"],
// obj是对象没有Symbol.iterator属性 所以自己创建
[Symbol.iterator]() {
let index = 0;
return {
// 手动创建next方法
next: () => {
if (index < this.jurisdiction.length) {
let result = {
value: this.jurisdiction[index],
done: false
}
index++
return result
} else {
return {
value: undefined,
done: true //done 为true value为undefined表示结束
}
}
}
}
}
}
// 要遍历jurisdiction
for (let item of obj) { //item是自命名 代表遍历中的每个元素
console.log(item);
}
13.生成器
生成器函数是 ES6 提供的一种异步编程解决方案。(后被promise代替 但还是有些需要使用,比如面试 哈哈哈哈)
function* gen() {
// yield 相当于函数的暂停标记,也可以认为是函数的分隔符,每调用一次 next方法,执行一段代码
yield '憨八龟';
yield "你在吗"
}
// 执行获取到的迭代器对象
let centre = gen()
// 生成器函数返回的结果是迭代器对象,调用迭代器对象的 next 方法可以得到yield 语句后的值
console.log(centre.next())
next 方法可以传递实参,作为 yield 语句的返回值
function* hen(num) {
console.log(num)
let one = yield "我的返回值是222";
console.log(one);
let two = yield "我的返回值是333";
console.log(two);
}
let centre = hen(111)
// **next 方法可以传递实参,作为 yield 语句的返回值**
centre.next() //注意第一个next 传参不会被V8引擎所识别 所以放在hen中传参
centre.next(222)
centre.next(333)