let 和 const
let
使用let声明的变量,没有变量提升
是一个块级作用域
不能重复声明
const
const用于声明常量,一旦被声明,就无法修改
其余特性和let一样
注意
在for循环中,使用let声明 i 的话,不会对 i 进行变量提升
使用let和const定义的变量个常量不会污染全局变量
在默认情况下用const,只有在知道变量值需要被修改的时候用let
模板字符串
使用反引号把要插入变量的字符串括起来,然后在插入变量的地方使用${变量名}就可以了
函数
默认值
可以给形参设置默认值,在调用函数的时候没有传参时,就会使用默认值
function fun(a = 5, b = 10){
return a + b;
}
console.log(fun());
默认表达式
形参的默认值可以是一个函数的返回值,也就是说可以是一个有返回值的函数
function fun(a = 5, b = getVal(6)){
return a + b;
}
function getVal(val){
return val + 10
}
console.log(fun());
剩余参数
由三个点(...),和一个紧跟着的参数名指定,如:...keys
可以把多个独立的参数合并到一个数组中
用于解决arguments的伪数组的问题
let book = {
title:'这是一本书',
author:'佚名',
year:'4202'
}
function pick(obj,...keys){
let result = Object.create(null);
for(let i = 0;i<keys.length;i++){
result[keys[i]] = obj[keys[i]];
}
return result;
}
let bookData = pick(book, 'title', 'author', 'year')
console.log(bookData);
扩展运算符
把一个数组分割,并且把其中的各个元素作为分离的参数传给函数
const arr = [10,50,15,11,90,30,40,20]
// 处理数组中的最大值,在es5中需要使用apply
console.log(Math.max.apply(null,arr));
// 在es6只需要使用扩展运算符即可,会自动比较
console.log(Math.max(...arr));
箭头函数
使用 => 来定义函数,function(){} 等于 () => {}
箭头函数没有this指向
注意:
使用箭头函数时,函数内部没有arguments
箭头函数不能使用new关键字来实例化对象
// 如果有两个参数
// let add = (a,b)=>{
// return a + b
// }
// console.log(add(10));
// 如果是一个参数
// let add = a => {
// return a + 10
// }
// console.log(add(10));
// 如果没有参数
// let add = () => {
// return 11 + 10
// }
// console.log(add());
// 如果函数中只有return,可以省略花括号和return关键字,如果需要返回一个对象或是数组,可以使用()包起来
let add = a => a + 10;
let add2 = id => ({id:id,name:'赵云'})
console.log(add(5));
console.log(add2(1))
解构赋值
解构赋值是对赋值运算符的一种扩展
针对数组和对象进行操作
let obj = {
name:'赵云',
age:18,
address:'常山'
}
let {name,age,address} = obj
console.log(name,age,address);
对象的方法
is()
等同于 ===
比较两个值是否严格全等
let a = 10
let b = 20
console.log(Object.is(a,b));
assign()
对象的合并,会返回合并之后的新对象
注意:
不同对象中如果有同名的属性,那么后面的对象的属性会覆盖前面的对象的属性
let obj1 = {
ccc:'赵云',
age:18
}
let obj2 = {
name:'张飞',
age:20
}
let newObj = Object.assign({},obj1,obj2)
console.log(newObj);
symbol
symbol是原始数据类型,表示是独一无二的值,不同的变量的地址也是不同的
一般用来定义对象的私有变量
注意:
如果用symbol定义了对象中的变量,在取值的时候一定要使用 对象[变量名] 的方式
如果对象中有用symbol定义的变量,那么这个变量就不能使用for..in等方式进行遍历
可以通过Object.getOwnPropertySymbols(对象名)来获取对象中的symbol变量
也可以通过Reflect.ownKeys(对象名)来获取对象中的symbol变量
const a = Symbol('name')
const b = Symbol('name')
console.log(a===b);
let c = {
[b]:"张飞"
}
c[a] = '赵云'
console.log(c);
console.log(c.a);
console.log(c[a]);
console.log(c[b]);
let s = Object.getOwnPropertySymbols(c)
console.log(s);
let m = Reflect.ownKeys(c)
console.log(m);
set集合
集合:表示无重复值的有序列表
想要使用必须先声明一个变量,然后实例化Set对象
add
向集合中添加一个数据
delete
删除集合中的一个数据
has
判断指定的数据在集合中是否存在
size
返回集合的长度
forEach
循环集合,但是在集合中值和键通常都是一样的,所以没有什么意义
[ ...集合名]
可以通过扩展运算符把集合转换为数组
注意:
在集合中的对象无法被释放
可以使用new WeakSet(),代替new Set(),但是WeakSet对象中的方法比Set对象中少
WeakSet():
只能传入对象作为值
不能循环遍历
没有forEach方法
没有size属性
let abc = new Set()
abc.add(10)
console.log(abc);
abc.delete(10)
console.log(abc);
console.log(abc.has(10))
console.log(abc.size);
abc.add(10)
abc.add(20)
abc.add(30)
abc.add(40)
abc.forEach((val,key)=>{
console.log(val);
console.log(key);
})
let arr = [...abc]
console.log(arr);
let set2 = new Set()
let set3 = new WeakSet()
let obj = {}
set2.add(obj)
set3.add(obj)
obj = null
console.log(set2);
console.log(set3);
Map
Map类型是键值对类型的有序列表,键和值可以是任意类型
let map1 = new Map()
map1.set('name','赵云')
map1.set('age',18)
console.log(map1);
console.log(map1.get('name'));
数组
from()
可以把伪数组转换为真正的数组,比如arguments
第一个参数就是要转换的伪数组
第二个参数是回调函数,用来对每个元素进行处理
function add(){
let arr = Array.from(arguments)
console.log(arr);
}
add(1,2,3)
of()
把一组值转换为数组
console.log(Array.of(1,2,3,4,5,6,"asd"));
copywidthin()
把指定下标的后面的元素复制到指定下标的位置,会把指定下标的原本的元素覆盖,会改变原数组
注意:
包括0,但不包括1,所以从下标为1的元素开始复制到下标为0的地方
let arr = [1,2,3,4,5,6]
arr.copyWithin(0,1)
console.log(arr);
find()
筛选数组,会返回满足条件的第一个元素,不会改变原数组,需要一个新的变量接收
let arr = [1,50,10,-20,100]
let arr2 = arr.find(val => val>60)
console.log(arr2);
keys()
会通过一组数据返回一个遍历器,然后可以使用for...of进行遍历的时候,可以通过变量获取数组的下标
就是对键名的遍历
for(let index of ['a','b'].keys()){
console.log(index);
}
values()
会通过一组数据返回一个遍历器,然后可以使用for...of进行遍历的时候,可以通过变量获取数组中每个元素
就是对值的遍历
for(let val of ['a','b'].values()){
console.log(val);
}
entries()
会通过一组数据返回一个遍历器,然后可以使用for...of进行遍历的时候,可以通过变量获取数组中每个元素,和元素的下标
就是对键值对的遍历
for(let [index,val] of ['a','b'].entries()){
console.log(index);
console.log(val);
}
编辑器.next()
可以通过next方法,获取到遍历器中的元素和下标
let arr = ['a','b','c'];
let arr2 = arr.entries()
console.log(arr2);
// console.log(arr2.next());
console.log(arr2.next().value);
console.log(arr2.next().value);
console.log(arr2.next().value);
includes
返回一个布尔值,表示数组中是否包含指定的值,效果和indexof类似
let arr = ['a','b','c'];
console.log(arr.includes('a'));
console.log(arr.includes(10));
迭代器
Iterator
是一种新的遍历机制
迭代器是一个接口,能快捷的访问数据,通过Symbol.iterator来创建迭代器,然后通过迭代器的next()方法获取迭代后的结果
迭代器用于遍历数据结构的指针
迭代器中有两个参数
第一个:value,代表值
第二个:done,代表是否遍历完成,false表示未完成遍历,true表示完成遍历
let arr = ['a','b','c'];
let arr2 = arr[Symbol.iterator]()
console.log(arr2.next());
console.log(arr2.next());
console.log(arr2.next());
console.log(arr2.next());
生成器
generator
可以通过yield关键字关键字,把函数挂起
与普通函数的区别:
function后面,函数名前面有个 *
只能在函数内部使用yield表达式
会返回一个遍历器对象,可以使用next方法
generator是分段执行的,yield语句是暂停执行,而next方法会恢复执行
生成器主要是用于为不具备interator接口的对象提供遍历操作
还可以用于让异步代码同步化
function* fun(a,b,c){
// 在使用next方法调用的时候,函数内部执行到这里的时候会把yield关键字修饰的东西挂起,后面就会停止执行,直到使用next方法继续执行
console.log('one');
yield a
console.log('two');
yield b
console.log('three');
yield c
}
let a = fun(10,20,30)
console.log(a.next());
console.log(a.next());
console.log(a.next());
console.log(a.next());
类
可以把一些东西抽象成类
子类可以继承父类,在子类中使用super()方法就可以把子类和父类共同的属性连接起来
在子类中可以重写父类的方法
class Person{
constructor(name,age){
this.name = name;
this.age = age;
}
getName(){
return this.name;
}
setName(name){
this.name = name;
}
}
let person = new Person('赵云',18)
console.log(person);
console.log(person.getName());
person.setName('张飞')
console.log(person.getName());
class Student extends Person{
constructor(name,age,className,address){
super(name,age)
this.className = className;
this.address = address;
}
getAge(){
return this.age;
}
}
let student = new Student('刘备',18,'一班','荆州')
console.log(student);
console.log(student.getAge());
student.setName('吕布')
console.log(student.getName());