基本用法:let命令用来声明变量,用法类似于var,区别所声明的变量只在let命令所在代码块内有效。
暂时性死区:在代码块内,使用let命令声明变量之前,该变量都是不可用的。
不允许重复声明:let不允许在相同作用域内重复声明同一个变量。
外层作用域无法读取内层作用域的变量。
内层作用域可以定义外层作用域的同名变量。
基本用法:声明一个只读常量,一旦声明,常量值不可以改变;若声明的是一个数组,数组的项可以改变,整个数组不行。只声明不赋值会报错。
暂时性死区:(同let命令 )
不可重复声明:(同let命令)
Object.freeze方法:冻结const声明的对象;对象的属性也可以冻结。
ES6声明变量有六种方式:var命令、function命令、let命令、const命令、import命令、class命令。
其中Let声明全局变量不是顶层对象。如下所示:
var a = 1;
window.a//1
let b = 2;
window.b//undefined
基本用法:从数组和对象中提取值,对象进行赋值,有序;解构不成功,变量值为undefined。
对数组进行赋值时,右边的值本身不具备iterator接口或转为对象不具备iterator接口都会报错。
简介:对象的属性没有次序,变量必须与属性同名,才能去得到值;若解构失败,变量值为undefined。
对象解构的内部机制:先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。如:
let{
foo:baz} = {
foo:'aaa',bar:'bbb'};
baz//"aaa"
foo//error:foo is not defined
(foo是匹配,baz是变量)
对象的解构赋值可以去到继承的属性:
const obj1 = {
};
const obj2 = {
foo:'bar'};
Object.setPrototypeOf(obj1,obf2);
foo//"bar"
上面代码中,对象obj1的原型对象是obj2。foo属性不是obj1自身的属性,而是继承自obj2的属性,解构赋值可以取到这个属性。
注意:大括号不可以写在行首,会报错。应该在整个解构赋值语句加上圆括号。
//错误的写法
let x;
{
x} = {
x:1};
//正确的写法
let x;
({
x} = {
x:1});
字符串被转成类似数组的对象,再赋值。
先转为对象,再赋值。
不能使用圆括号的情况:
①变量声明语句
②函数参数
③赋值语句的模式部分(区别于3.2的注意点)
//以下三种全部报错
[({
p:a}),{
x:c}] = [{
},{
}];
({
p:a}) = {
p:42};
([a]) = [5];
可以使用圆括号的情况只有一种:赋值语句的非模式部分 。
//以下三个为正确的写法
[(b)] = [3];
({
p:(d)} = {
});
[(parseInt.prop)] = [3];
赋值语句的模式部分与非模式部分的区别:模式是取数组第一个成员;模式是p,而不是d;
参数是字符串,第二个参数表示正则表达式的修饰符:RegExp(‘xyz’, ‘i’)。
参数的正则表达式,返回原有的正则表达式:RegExp(/xyz/i)。
参数第一个是正则对象,第二个参数则会覆盖正则的修饰符:RegExp(/xyz/ig,’i’)。
y修饰符和g修饰符类似,都是全局匹配,后一次匹配从上一次匹配成功的下一个来时位置开始;区别g只要剩余位置有匹配就可,而y要第一位置才可。
表示是否设置了y修饰符
返回正则表达式的修饰符
基本用法:用前缀0b(或0B)和0o(或0O)表示。
参数变量是默认声明的,不能用let或const再次声明。
默认参数:采用惰性求值方式。
参数默认值的位置:当有默认值是,调用其方法也因在对应参数写上undefined。
函数的length属性:length属性的返回值,等于函数的参数个数减去指定默认参数个数;如果默认参数不是尾参数,返回值不再计入后面的参数。
rest参数后不能有其他的参数。
函数的length属性,不包括rest参数。
基本用法:在全局中设置严格模式;函数包在一个无参数的立即执行的函数里面。
报错情景:函数参数使用了默认值、解构赋值、扩展运算符,函数内部设置了严格模式。
基本用法:
①箭头函数不需要参数或需要多个参数时,使用一个圆括号代表参数部分。
②箭头函数的代码块部分多于一条语句时,使用大括号将它们括起来,并使用return语句返回。
③箭头函数返回一个对象时,必须在对象外面加上括号,否则报错。
注意事项:
①函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
②不可以用构造函数(new命令)
③不可以使用arguments对象。
④不可以使用yield命令。
不适用的场合:
①定义对象的方法,且该方法内部包括this,则不能用。
②需要动态this的时候,也不能用。
嵌套的箭头函数
基本用法:只保留内层函数的调用帧。
含义:扩展运算符是三个点(…)。
用途:主要用于函数的调用。
用法:后可放置表达式。
扩展运算符的应用:
①复制数组:例如const a1 = [1,2];复制a1的方法有
(1)const a2 = […a1];(2)const[…a2 = [a1];
②合并数组:[…数组1,…数组2,数组3]
③与解构赋值结合
若用于数组的解构赋值,只能放在最后一位。
④字符串:可以将字符串转为真正的数组。
⑤实现可iterator接口的对象
⑥map 和 set 结构,generator函数这三个都有iterator接口,都可以使用扩展运算符。
用途:将两类对象转为真正的数组(数组的对象和可遍历的对象)
用途:用于将一组值转换为数组。
Array.prototype.copyWithin(target, start = 0, end = this.length)
其中:target(必选):从该位置开始替换数据。Start(从该位置开始)和end(到该位置前停止读取数据)为可选。
find()是查找出第一个符合条件的数组成员没有返回undefined;findIndex()没有返回-1。
表示独一无二的值;即使参数相同,也不相等。用于常量状态识别。
魔术字符串的特征:在代码中多次出现,与代码形成“强耦合”。
消除方法:把魔术字符串写成一个变量。
其中Symbol.for()和Symbol.keyFor()都表示重新使用同一个symbol值。
基本用法:成员值都是唯一的;成员什么都可以。
属性和遍历操作方法:两个属性和四个方法(keys();values();entries();forEach())。
含义:成员值都是唯一;且成员只能是对象。
Map的键实际上是跟内存地址绑定的,只要内存地址不一样,就视为两个键。
只接受对象作为键名。
没有遍历操作方法,只有四个方法(get()、set()、has()、delete())。
Proxy可以理解为拦截器。
Apply():拦截函数的调用,接受三个参数(目标对象、目标对象的上下文对象和目标对象的参数数组。)
Has():拦截HasProperty操作,接受两个参数(目标对象、需查询的属性名)。
Construct():拦截new命令,接受两个参数(目标对象、构造函数的参数对象)。
DeleteProperty():拦截delete操作。
DefineProperty():拦截Object.defineProperty操作。
getOwnPropertyDescriptor():拦截Object.getOwnPropertyDescriptor()操作。
ownKeys():拦截对象自身属性的读取操作。
preventExtensions():拦截Object.preventExtensions()。
setPrototypeOf():拦截Object.setPrototypeOf方法。
该方法返回一个可以取消的Proxy实例。
含义:简单的说就是一个容器。
特点:对象的状态不受外界影响;状态改变,就不会再变。
特征:function关键字与函数名之间有一个星号;函数体内部使用yield表达式,定义不同的内部状态。
在generator函数内部,调用另外一个generator函数,默认是没有效果的。
Yield表达式:表示暂停;只能在generator函数里面使用,其他地方会报错;用在另外一个表达式中,必须放在圆括号里面。