关键词
let
用来声明变量,它的用法类似于var。
特点
- 声明的变量,只在
let
命令所在的代码块内有效 - 在同⼀作⽤域内不允许重复声明
- 不存在变量提升
- 暂时性死区(在let声明变量之前无法操作或读取这个变量)
const
声明一个只读的常量。一旦声明,常量的值就不能改变。
特点
- 不能重新赋值
- 只是保证内存地址是不变的(对于简单数据类型,字符串,数字,布尔类型就保存在相应内存地址上,而复杂类型,如对象,数组等,实际只是保存了指向其的指针)
- 不存在变量提升
- 暂时性死区(在let声明变量之前无法操作或读取这个变量)
注意
- 变量声明的同时,必须立即赋值
- 声明的是简单类型的数据,变量的值不可改变
数据类型Symbol
ES6 引入了一种新的原始数据类型Symbol ,表示独一无二的值。它属于 JavaScript 语言的数据类型之一,其他数据类型是:undefined、null、布尔值(Boolean)、字符串(String)、数值(Number)、大整数(BigInt)、对象(Object)。
Symbol类型的数据是类似字符串的数据类型,由于Symbol函数返回的值是原始类型的数据,不是对象,故Symbol函数前不能使用new命令,否则会报错。
Symbol 作为对象属性名时不能用.运算符,要用方括号。因为运算符后面是字符串,所以取到的是字符串 sy 属性,而不是 Symbol 值 sy 属性。
let a1 = Symbol('xxx');
let a2 = Symbol('xxx');
console.log(a1===a2);//fasle
console.log(a1);//Symbol(xxx)
console.log(a2);//Symbol(xxx)
如果要读取到一个对象的 Symbol 属性,可以通过 Object.getOwnPropertySymbols() 和 Reflect.ownKeys() 取到。
Symbol.for()、Symbol.keyFor()方法
Symbol.for() 类似单例模式,首先会在全局搜索被登记的 Symbol 中是否有该字符串参数作为名称的 Symbol 值;如果有即返回该 Symbol 值,若没有则新建并返回一个以该字符串参数为名称的 Symbol 值,并登记在全局环境中供搜索
Symbol.keyFor()方法返回一个已登记的 Symbol 类型值的key;
解构赋值
ES6中只要某种数据有Iterator接口(也就是可以循环迭代),都可以进行数组的解构赋值。
针对数组或者对象进行模式匹配,然后对其中的变量进行赋值。
... :是es6中的扩展运算符,它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列。
{
let a,other
[a,...other] = [1,2,3,4,5,6,7,8,9,0]
console.log(other); //(9) [2, 3, 4, 5, 6, 7, 8, 9, 0]
}
解构赋值可以理解为赋值操作的语法糖;它是针对数组或者对象进行模式匹配,然后对其中的变量进行赋值
//应用场景:后端返回数据与前端变量名不同
{
function fn() {
return {
name: 'xiaoming',
namelist: {
name: 'TOM'
}
}
}
let b = fn();
let person, otherperson;
({ name: person, namelist: { name: otherperson } } = b)
console.log(name,otherperson);//xiaoming TOM
}
字符串的扩展
字符串的遍历接口:for of;除了遍历字符串,这个遍历器最大的优点是可以识别大于0xFFFF
的码点,传统的for
循环无法识别这样的码点
//传统for循环 处理不了超出范围的字符,但是for of可以
const str = '\u{20bb7}'
for(let i = 0;i<str.length;i++){
console.log(str[i]); //�}
for(let item of str){
console.log(item); //𠮷}
新增方法
确定一个字符串是否包含在另一个字符串中
- includes(string, position):返回布尔值,表示是否找到了参数字符串。
- startsWith(string, position):返回布尔值,表示参数字符串是否在原字符串的头部。
- endsWith(string, position):返回布尔值,表示参数字符串是否在原字符串的尾部
返回一个新字符串,表示将原字符串重复n
次。
- repeat(n)
某个字符串不够指定长度,会在头部或尾部补全
- padStrat(length, str) 用于头部补全
- padEnd(length, str) 用于尾部补全
let str = '123msydyufhreky73467'
console.log('includes',str.includes('yu')); //true
console.log('startsWith',str.startsWith('123')); //true
console.log('endsWith',str.endsWith('yu')); //false
let str1 = '你好'
console.log('repeat',str1.repeat(3)); //你好你好你好
消除空格
trmeStart(): 消除字符串头部的空格,返回的是新字符串,不会修改原始字符串
trmeEnd(); 消除字符串尾部的空格,返回的是新字符串,不会修改原始字符串
模板字符串
在模板字符串串中如需使⽤用反引号,反引号前要⽤用反斜杠转义;所有的空格和缩进都会被保留在输出之中;大括号中的值不是字符串时,将按照一般的规则转为字符串。比如,大括号中是一个对象, 将默认调用对象的toString方法;模板字符串中的${. .. } 大括号内部可以放入任意的 JavaScript 表达式,可以进行运算、可以引用对象属性、可以调用函数、可以甚至还能嵌套,甚至还能调用自己本身。
引入:${变量名}
//模板字符串
const name = 'tom';
const age = 22;
const hobbies = 'eat,drink'
//es5
const str = '我的名字'+name+'我今年'+age+'我爱'+hobbies
console.log(str);//我的名字tom我今年22我爱eat,drink
//es6
const es6str = `我的名字:${name},我今年:${age},我爱${hobbies}`
console.log(es6str);//我的名字:tom,我今年:22,我爱eat,drink
//es6的反引号 换行、空格等都可以拿过来
数组的扩展
复制数组
让一个数组等于另外一个数组,另外的数组改变,他也会跟着改变;...扩展运算符相当于是开辟了一个新的空间
let arr = [1,2,3,4,5,6];
let arr1 = [...arr]
console.log(arr1); //[1, 2, 3, 4, 5, 6]
arr.push(88);
console.log(arr1); //[1, 2, 3, 4, 5, 6]
合并数组
const arr1 = ['a', 'b'];
const arr2 = ['c'];
const arr3 = ['d', 'e'];
// ES5 的合并数组
arr1.concat(arr2, arr3);
// [ 'a', 'b', 'c', 'd', 'e' ]
// ES6 的合并数组
[...arr1, ...arr2, ...arr3]
// [ 'a', 'b', 'c', 'd', 'e' ]
方法
填充一个数组
- arr.fill(value, start, end): 第一个参数是填充值,第二个和第三个参数,用于指定填充的起始位置和结束位置
遍历数组。都返回一个遍历器对象
- entries()
- keys()
- values()
区别是keys()
是对键名的遍历、values()
是对键值的遍历,entries()
是对键值对的遍历。
判断当前数组是否存在某个值,返回布尔型
- includes()
[1, 2, 3].includes(2) // true
[1, 2, 3].includes(4) // false
多维数组转为一维数组
- falt()
- faltMap() :只能展开一层数组;对原数组的每个成员执行一个函数(相当于执行
Array . prototype .map()
),然后对返回值组成的数组执行flat()
方法。该方法返回一个新数组,不改变原数组。
// flat 展开多维数组
let arr = [1,2,3,['second',3,4,5,['33',4,5,6]]]
let arr1 = arr.flat()
console.log(arr1);// [1, 2, 3, "second", 3, 4, 5, Array(4)]
let arr2 = arr.flat(3)
console.log(arr2); //[1, 2, 3, "second", 3, 4, 5, "33", 4, 5, 6]
对象的扩展
复制对象 /给对象设置默认值 /合并对象
//复制对象
const obj = {name:'tom',age:22}
const objA = {color:'pink'}
let obj1 = {...obj};
console.log(obj1); //{name: "tom", age: 22}
//设置默认值
let obj2 = {...obj,name:'May'}
console.log(obj2); //{name: "May", age: 22}
//合并对象
let obj3 = {...obj,...objA};
console.log(obj3); //{name: "tom", age: 22, color: "pink"}
新增方法
Object.is 判断两个值是否相同
(+0不等于-0;NaN等于自身;NaN在js里面与任何值都相等,包括他自己本身,在Object.is中没有这个特性)
let r1 = Object.is(NaN,NaN);
console.log(r1,NaN===NaN);//true false
Object.assign 对象合并(如果对象中还包含对象,复制的是指针)
let person = {name:'Tom',age:22}
let person1 = {gander:'man'}
Object.assign(person1,person)
console.log(person1);//{gander: "man", name: "Tom", age: 22}
person.age = 18;
console.log(person1);//{gander: "man", name: "Tom", age: 22}
Object.keys 遍历对象中的key,返回数组
Object.values 遍历对象中的values,返回数组
Object.entries 遍历键值对,返回数组
const json = {name:'Tom',age:22,gander:'man',hobbies:'eat'}
console.log(Object.keys(json));//["name", "age", "gander", "hobbies"]
console.log(Object.values(json));//["Tom", 22, "man", "eat"]
console.log(Object.entries(json));//[Array(2), Array(2), Array(2), Array(2)]
Set
值得集合;它和数组的最大的区别就在于: 它的值不会有重复项
API
- size():返回成员个数
- clear():清除所有成员,没有返回值。
- add():添加某个值,返回 Set 结构本身。
- has():返回一个布尔值,表示该值是否为Set的成员。
- delete():删除某个值,返回一个布尔值,表示删除是否成功
let set1 = new Set(['1', 2, 3]);
set1.add(1)
console.log(set1);// {"1", 2, 3, 1}
console.log('长度', set1.size); //长度 4
let item = { color: 'blue' }
let set = new Set();
set.add({ color: 'blue' })
console.log(set); //Set(1) {{…}}
console.log(set.has({ color: 'blue' })) //false
set1.add(item)
console.log(set1.has(item));//true
遍历操作
keys()
:返回键名的遍历器values()
:返回键值的遍历器entries()
:返回键值对的遍历器forEach()
:使用回调函数遍历每个成员
//使用场景:数组去重
let arr = [1,1,2,2,3,3,4,4]
let set = new Set(arr);
console.log(set); //Set(4) {1, 2, 3, 4}
let arr1 = Array.from(set);//类数组转成真数组
console.log(arr1);//[1, 2, 3, 4]
WeakSet
WeakSet 结构与 Set 类似,也是不重复的值的集合。但是,它与 Set 有两个区别。
首先,WeakSet 的成员只能是对象,而不能是其他类型的值。其次,WeakSet 中的对象都是弱引用,即垃圾回收机制不考虑 WeakSet 对该对象的引用,也就是说,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于 WeakSet 之中。
Map
键值对的集合;
API
- size():返回 Map 结构的成员总数
- clear():清除所有成员,没有返回值。
- set():设置键名key对应的键值为value,然后返回整个 Map 结构。如果key已经有值,则键值会被更新,否则就新生成该键。
- has():返回一个布尔值,表示某个键是否在当前 Map 对象之中。
- delete():删除某个键,返回
true
。如果删除失败,返回false
- get():读取key对应的键值,如果找不到key,返回undefined
遍历方法
keys()
:返回键名的遍历器。values()
:返回键值的遍历器。entries()
:返回所有成员的遍历器。forEach()
:遍历 Map 的所有成员
let map = new Map([
['name', 'Tom'],
['age', 22]
])
for (let entry of map) {
console.log(entry);//["name", "Tom"] ["age", 22]}
map.forEach((value,key) => {
console.log(`${key}:${value}`); //Tom:name 22:age })
WeakMap
与Map结构类似,也是用于生成键值对的集合;只接受对象作为键名 不接受任何其他类型;键名所指对象可以触发垃圾回收机制 自动回收;没有clear size方法 无法遍历。
Map、Set、数组和对象的相互转换
(1)Map转数组
使用扩展运算符(...)
const myMap = new Map()
.set(true, 7)
.set({foo: 3}, ['abc']);
[...myMap]
// [ [ true, 7 ], [ { foo: 3 }, [ 'abc' ] ] ]
(2)数组转Map
将数组传入 Map 构造函数,就可以转为 Map。
new Map([
[true, 7],
[{foo: 3}, ['abc']]
])
// Map {
// true => 7,
// Object {foo: 3} => ['abc']
// }
(3)Set转对象
如果所有 Map 的键都是字符串,它可以无损地转为对象;如果有非字符串的键名,那么这个键名会被转成字符串,再作为对象的键名
function strMapToObj(strMap) {
let obj = Object.create(null);
for (let [k,v] of strMap) {
obj[k] = v;
}
return obj;
}
const myMap = new Map()
.set('yes', true)
.set('no', false);
strMapToObj(myMap)
// { yes: true, no: false }
(4)对象转Set
对象转为 Map 可以通过Object.entries()
(Object.fromEntries() 方法把键值对列表转换为一个对象)
let obj = {"a":1, "b":2};
let map = new Map(Object.entries(obj))
参考:ES6 入门教程