声明变量方式
let
-
声明的变量有局部作用域
-
不存在变量提升, 只要块级作用域内存在
let命令,这个区域就不再受外部影响 -
let声明变量之前,该变量都不可用,即暂时性死区let不允许在相同作用域声明重复的变量
const
-
声明的是一个常量,指声明后变量的值就不允许被修改
我们对于一些后期不改变的数据可以使用const去声明
-
如果之前用
var或let声明过变量,再用const声明同样会报错 -
const实际上保证的并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动: -
赋值问题 对于简单类型的数据,值就保存在变量指向的那个内存地址,因此等同于常量。
对于复杂类型的数据,变量指向的内存地址,保存的只是一个指向实际数据的指针,const只能保证这个指针是固定的,并不能确保改变量的结构不变。
const定义的数据是一个简单数据类型的时候,是不能修改的,但如果是一个复杂数据类型是可以修改的,因为对于数据的存放是有栈、堆之说的,当我存简单数据类型的时候,是放在栈中。
而对于复杂数据类型,是将它的地址放在栈中,真正的数据放在堆中,当我数据变化的时候并不会去修改我的地址,所以用const可以修改对象中的值。
区别
-
变量提升
var 声明的变量存在比那里提升,即声明变量之前调用,值为 undefined。
let、const 不存在变量提升,即声明变量之前调用,报错。
-
暂时性死区
var 不存在暂时性死区
let 、const 存在暂时性死区,只有声明变量代码出现,才可以去使用该变量。
-
块级作用域
var 不存在块级作用域
let、const 存在块级作用域
-
重复声明
var 允许重复声明,
let、const 在同一作用域不允许重复声明
-
修改声明的变量
var 和 let 可以
const 不可以修改
-
使用问题
能使用const的情况就使用const,其他情况使用 let ,避免使用 var声明变量
数组新增
扩展运算符的应用
1、扩展运算符..., 三个点表示。
2、可以将某些数据结构转为数组,能够更简单实现数组复制,数组的合并也更为简洁。
3、扩展运算符可以与解构赋值结合起来,用于生成数组。
4、如果将扩展运算符用于数组赋值,只能放在参数的最后一位,否则会报错, 可以将字符串转为真正的数组
find()、findIndex()
一、find()
1、find 用于找出第一个符合条件的成员,
2、参数是一个回调函数,接收三个参数,依次为【当前值、索引、原数组】
一、findIndex()
1、返回符合条件的第一个数组成员的位置(索引),如果所有条件都不符合,则返回 `-1`
entries(),keys(),values():
1、 `keys()`是对键名的遍历
2、 `values()`是对键值的遍历
3、 `entries()`是对键值对的遍历
includes():用于判断数组是否包含给定的值
1、方法的第二个参数表示搜索的起始位置,默认为`0`。
2、 参数为负数则表示倒数的位置
对象新增
属性的简写
1、ES6中,当对象键名与对应值名相等的时候,可以进行简写。方法也能够进行简写。在函数内作为返回值,也会变得方便很多。
2、注意:简写的对象方法不能用作构造函数,否则会报错。
属性的遍历
1、ES6 一共有 5 种方法可以遍历对象的属性:
- for...in:循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)
- Object.keys(obj):返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名
- Object.getOwnPropertyNames(obj):回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名
- Object.getOwnPropertySymbols(obj):返回一个数组,包含对象自身的所有 Symbol 属性的键名
- Reflect.ownKeys(obj):返回一个数组,包含对象自身的(不含继承的)所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举
上述遍历,都遵守同样的属性遍历的次序规则:
1、首先遍历所有数值键,按照数值升序排列
2、其次遍历所有字符串键,按照加入时间升序排列
3、最后遍历所有 Symbol 键,按照加入时间升序排
对象新增的方法
- Object.is():
严格判断两个值是否相等,与严格比较运算符(===)的行为基本一致,不同之处只有两个:一是`+0`不等于`-0`,二是`NaN`等于自身
- Object.assign():
Object.assign()方法用于对象的合并,将源对象source的所有可枚举属性,复制到目标对象target
Object.assign()方法的第一个参数是目标对象,后面的参数都是源对象
注意:Object.assign()方法是浅拷贝,遇到同名属性会进行替换
- Object.getOwnPropertyDescriptors():返回指定对象所有自身属性(非继承属性)的描述对象
- Object.setPrototypeOf():用来设置一个对象的原型对象
- Object.getPrototypeOf():用于读取一个对象的原型对象
- Object.keys():返回自身的(不含继承的)所有可遍历(enumerable)属性的键名的数组
- Object.values():返回自身的(不含继承的)所有可遍历(enumerable)属性的键对应值的数组
- Object.entries():返回一个对象自身的(不含继承的)所有可遍历(enumerable)属性的键值对的数组
- Object.fromEntries():用于将一个键值对数组转为对象
箭头函数
- 如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分
- 如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用return语句返回
- 如果返回对象,需要加括号将对象包裹
注意点:
1、函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象
2、不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误
3、不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替
4、不可以使用yield命令,因此箭头函数不能用作 Generator 函数
Set Map
定义
1、Set是一种叫做集合的数据结构,Map是一种叫做字典的数据结构
2、什么是集合和字典。
集合:是由一堆无序的、相关联的,且不重复的内存结构【数学中称为元素】组成的组合
字典:是一些元素的集合。每个元素有一个称作key 的域,不同元素的key 各不相同
区别
共同点:集合、字典的值都是不可以重复的。
不同点:Set是以 [值, 值] 的形式储存;Map 是以 [键:值]的 形式储存
Set
1、Set是es6新增的数据结构,类似于数组,但里边的值都是不允许重复的,我们成为集合。
2、增删改查
add(): 添加某个值,返回Set结构本身,当添加实例中已存在的元素,Set 不会进行处理
delete(): 删除某一个值,返回布尔值,表示是否成功
has(): 返回布尔值,判断该值是否为Set的成员
clear(): 清除所有成员,没有返回值
Map
1、Map类型是键值对的有序列表,而键和值都可以是任意类型
2、增删改查:
size():size属性返回 Map 结构的成员总数。
set():设置键名key对应的键值为value,然后返回整个 Map 结构。如果key已经有值,则键值会被更新,否则就新生成该键。同时返回的是当前Map对象,可采用链式写法
get():get方法读取key对应的键值,如果找不到key,返回undefined。
has():has方法返回一个布尔值,表示某个键是否在当前 Map 对象之中。
delete():delete方法删除某个键,返回true。如果删除失败,返回false。
clear():clear方法清除所有成员,没有返回值
Promise
定义
-
是异步编程的一种解决方案,也是解决 穿发那个方案的(回调地狱)更加合理。
-
三个状态:
padding进行中,ulfilled(已成功)、rejected(已失败) -
优点:可以链式编程,可读性增强
const promise = new Promise( ( resolve, reject )=> {
})
resolve`函数的作用是,将`Promise`对象的状态从“未完成”变为“成功”
reject`函数的作用是,将`Promise`对象的状态从“未完成”变为“失败
- 实例方法:
Promise构建出来的实例存在以下方法
1、.then(): 实例发生改变的回调函数,参数1:是resolved的回调,参数2:rejected的回调。
2、.catch(): 是发送错误的回调。
3、inally():用于指定不管 Promise 对象最后状态如何,都会执行的操作。
- 构造函数方法:Promise构造函数存在以下方法
1、all():Promise.all()方法用于将多个 Promise实例,包装成一个新的 Promise实例
2、race():Promise.race()方法同样是将多个 Promise 实例,包装成一个新的 Promise 实
3、allSettled():Promise.allSettled()方法接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例
4、resolve():将现有对象转为 Promise对象
5、reject():Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected
Proxy
const proxy = new Proxy ( target, handler )
参数
target表示所要拦截的目标对象(任何类型的对象,包括原生数组,函数,甚至另一个代理))handler通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理p的行为
使用场景
- 拦截和监视外部对对象的访问
- 降低函数或类的复杂度
- 在复杂操作前对操作进行校验或对所需资源进行管理
Module
定义
- 模块化管理
方案
CommonJs
使用node的道友应该知道···
1、它是通过require来引入模块,通过module.exports定义模块的输出。
2、这种模块的加在方案是服务器端的解决方案,同步的方式引入。
3、服务器的文件都是储存本地磁盘,读取文件块,所以同步加在没有问题。
4、如果是浏览器端,由于模块的加载是网络请求,因为使用异步的加载方式更加合适。
AMD
典型代表:require.js
1、这种方案采用异步加载的方式来加载模块,模块加载不影响后面语句的执行
2、所有依赖模块的方法语句都在一个回调中,加载完成后在执行回调函数,require.js实现了AMD的规范
CMD
1、 这种方案和 AMD 方案都是为了解决异步模块加载的问题,sea.js 实现了 CMD 规范。
2、 它和require.js的区别在于模块定义时对依赖的处理不同和对依赖模块的执行时机的处理不同。
ES6 Module
1、 ES6 提出的方案,使用 import 和 export 的形式来导入导出模块。 2、可以默认导出/导入,和按需导出/引入