1、let:声明的变量只在let命令所在的代码块内有效(块级作用域)
1)局部变量:在函数体内使用var和let关键字声明的变量有点类似。它们的作用域都是局部的
2)全局变量:在函数体外或代码块外使用var和let关键字声明的变量也有点类似。它们的作用域都是全局的
3)HTML代码中使用全局变量:在JavaScript中,全局作用域是针对JavaScript环境
在HTML中,全局作用域是针对window对象
使用var关键字声明的全局作用域变量属于window对象
使用let关键字声明的全局作用域变量不属于window对象
4)重置变量:A、使用var关键字声明的变量在任何地方都可以修改
B、在相同的作用域或块级作用域中,不能使用let关键字来重置var关键字/let关键字声明的变量
C、在相同的作用域或块级作用域中,不能使用var关键字来重置let关键字声明的变量
D、let关键字在不同作用域或不同块级作用域中是可以重新声明赋值的
5)变量提升:A、var关键字定义的变量可以在使用后声明,也就是变量可以先使用再声明
B、let关键字定义的变量不可以在使用后声明,也就是变量需要先声明再使用
2、const:用于声明一个或多个常量,声明时必须进行初始化且初始化后值不可再修改(块级作用域)
1)重置变量:A、使用var关键字声明的变量在任何地方都可以修改
B、在相同的作用域或块级作用域中,不能使用const关键字来重置var关键/let关键字/const关键字声明的变量
C、const关键字在不同作用域或不同块级作用域中是可以重新声明赋值的
2)变量提升:A、var关键字定义的变量可以在使用后声明,也就是变量可以先使用再声明
B、const关键字定义的变量不可以在使用后声明,也就是变量需要先声明再使用
3、箭头函数:箭头函数提供了一种更加简洁的函数书写方式
语法:参数 => 函数体
1)无参数无返回值:
var show = () => alert("hello world");
2)有参数无返回值:
var show = (num1, num2) => {
}
3)有参数有返回值:
var show = (num1, num2) => num1 + num2;
4、解构赋值:对赋值运算符的扩展。针对数组或对象进行模式匹配,然后对其中的变量进行赋值。在代码书写上简洁且易读,语义更加清晰明了,也方便了复杂对象中数据字段获取
1)数组模型的解构:
A、基本:
let [a, b, c] = [1, 2, 3];
B、可嵌套:
let [a, [[b], c]] = [1, [[2], 3]];
C、可忽略:
let [a, , b] = [1, 2, 3];
D、不完全解构:
let [a = 1, b] = [];
E、剩余运算符:
let [a, ...b] = [1, 2, 3];
F、字符串等:
let [a, b, c, d, e] = 'hello';
G、解构默认值:
let [a = 2] = [undefined];
2)对象模型的解构:
A、基本:
let { foo, bar } = { foo: 'aaa', bar: 'bbb' };
let { baz : foo } = { baz : 'ddd' };
B、可嵌套:
let obj = {p: ['hello', {y: 'world'}] };
let {p: [x, { y }] } = obj;
C、可忽略:
let obj = {p: ['hello', {y: 'world'}] };
let {p: [x, { }] } = obj;
D、不完全解构:
let obj = {p: [{y: 'world'}] };
let {p: [{ y }, x ] } = obj;
E、剩余运算符:
let {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40};
F、解构默认值:
let {a = 10, b = 5} = {a: 3};
let {a: aa = 10, b: bb = 5} = {a: 3};
5、模板字符串:模板字符串相当于加强版的字符串,用反引号`。除了作为普通字符串,还可以用来定义多行字符串,还可以在字符串中加入变量和表达式
字符串插入变量和表达式:变量名写在${}中,${}中可以放入JavaScript表达式
1)普通字符串:
let string = `Hello'\n'world`;
2)多行字符串:
let string1 = `Hey,
can you stop angry now?`;
3)字符串插入变量和表达式:
let name = "Mike";
let age = 27;
let info = `My Name is ${name},I am ${age+1} years old next year.`
4)字符串中调用函数:
function f(){
return "have fun!";
}
let string2= `Game start,${f()}`;
注意:1)模板字符串中的换行和空格都是会被保留的
2)当模板字符串中带有变量,会将模板字符串参数处理成多个参数
6、数组:1)Array.from():将类数组对象或可迭代对象转化为数组
类数组对象:必须含有length属性,且元素属性名必须是数值或者可转换为数值的字符
Array.from(object, mapFunction, thisValue)
object:要转换的类数组对象或可迭代对象
mapFunction:可选,数组中每个元素要调用的函数
thisValue:可选,映射函数(mapFunction)中的this对象
2)copyWithin():将一定范围索引的数组元素修改为此数组另一指定范围索引的元素
array.copyWithin(target, start, end)
target:复制到指定目标索引位置
start:元素复制的起始位置
end:可选,停止复制的索引位置(默认为array.length)。如果为负值则表示倒数
3)find():查找数组中符合条件的元素,若有多个符合条件的元素则返回第一个元素
array.find(function(currentValue, index, arr),thisValue)
function(currentValue, index,arr):数组每个元素需要执行的函数
currentValue:当前元素
index:可选,当前元素的索引值
arr:可选,当前元素所属的数组对象
4)findIndex():查找数组中符合条件的元素索引,若有多个符合条件的元素则返回第一个元素索引
array.findIndex(function(currentValue, index, arr), thisValue)
7、对象:Object.assign():用于将源对象的所有可枚举属性复制到目标对象中
注意:1)如果目标对象和源对象有同名属性或者多个源对象有同名属性,后面的属性会覆盖前面的属性
2)如果该函数只有一个参数,当参数为对象时直接返回该对象。当参数不是对象时会先将参数转为对象然后返回
3)assign的属性拷贝是浅拷贝
8、Symbol:一种新的原始数据类型,表示独一无二的值。最大的用法是用来定义对象的唯一属性名
Symbol函数栈不能用new命令,因为Symbol是原始数据类型而不是对象
9、Map():Map对象保存键值对。任何值(对象或者原始值)都可以作为一个键或一个值
Map的迭代:1)for...of
2)forEach()
10、Set():Set对象允许存储任何类型的唯一值,无论是原始值或者是对象引用
Set中的特殊值:Set对象存储的值总是唯一的,所以需要判断两个值是否恒等
1)+0与-0在存储判断唯一性的时候是恒等的,所以不重复
2)undefined与undefined是恒等的,所以不重复
3)NaN与NaN是不恒等的,但在Set中只能存一个,所以不重复
数组去重:
var mySet = new Set([1, 2, 3, 4, 4]);
[...mySet];
11、Generator函数:通过yield关键字,把函数的执行流挂起,为改变执行流程提供了可能,从而为异步编程提供解决方案
function* func(){
console.log("one");
yield '1';
console.log("two");
yield '2';
console.log("three");
return '3';
}
func().next();
func().next();
func().next();
func().next();
第一次调用next方法时从函数的头部开始执行,先是打印了one,执行到yield就停下来并将yield后边表达式的值'1'作为返回对象的value属性值,此时函数还没有执行完返回对象的done属性值是false
第二次调用next方法时同上步
第三次调用next方法时先是打印了three,然后执行了函数的返回操作并将return后面的表达式的值作为返回对象的value属性值,此时函数已经结束,done属性值为true
第四次调用next方法时函数已经执行完毕,所以返回value属性值是undefined,done属性值是true。如果执行第三步时没有return语句就直接返回{value: undefined, done: true}