ES6 笔记(一)
一 :关键字扩展
1:块级作用域
- 块作用域由{}包括,if语句和for语句中{}也属于块作用域,块内使用let声明的变量,只会在当前块内有效。
- 块级作用域可以任意嵌套。
- 使用块级作用域可以防止全局变量污染。
{ //块级作用域 }
同:
(function(){...})()
- 建议函数在顶层作用域和函数作用域中声明,尽量避免在块级作用域中声明,如有需要,应写为函数表达式方式。
2:let关键字
let声明的变量,只在命令所在代码块内生效,即增加了块级作用域。
特点:
- let命令不存在变量提升
- 不允许重复声明
- 块级作用域出现,立即执行函数不再需要
- 不影响作用域链
- 不再是顶层全局对象的属性
3:const关键字
const声明必须赋初始值;声明一个只读变量,声明后不允许改变;值不允许修改。
const 保证变量指向的内存地址不允许变动
**特点:**同let。
二:变量的解构赋值
解构赋值本质就是赋值:把结构解散重构然后赋值,是对赋值运算符=的一种扩展。
赋值语法:
解构的目标 = 解构源
解构目标:定义的常量或变量
解构源:待解构的数组或对象
1:对象解构赋值
{
const {a,b,c} = {a:1,b:2,c:3};
console.log(a,b,c) //1,2,3
}
顺序不用一一对应;= 右侧可以是一个由对象赋值的常量或变量
- 嵌套对象解构
const {a,b,c:{d,e}} = {a:1,b:1,c:{d:2,e:2}};
console.log(a,b,d,e) // 1,1,2,2
- 可忽略解构源的属性
const{a,b} = {a:1,b:2,c:3,d:4};
console.log(a,b); // 1,2
- 剩余运算符
const {a,...b} = {a:1,b:2,c:3,d:4};
console.log(b); //{b: 2, c: 3, d: 4}
- 不完全结构
const {a,b,c,d} = {a:1,b:1};
console.log(a,b,c,d); // 1,1,undefined,undefined
- 解构默认值
const {a,b = 1} = {a:1};
consloe.log(a,b) //1,1
const {a,b = 1} = {a:1,b:2};
console.log(a,b) //1,2
- 函数传参数
function fn({a,b,c}) {console.log(a,b,c)};
fn({a:1,b:2,c:3}) //1,2,3
- 解构赋值时,如等号右侧为undefined或null会报异常
2:数组解构赋值
- 基本语法
let [a,b,c,d] = [1,2,3,4];
console.log(a,b,c,d); //1,2,3,4
- 忽略元素
let [,,,d] = [1,2,3,4];
console.log(d);
- 赋值上下文
let a = 100;
let b = 100;
[a,b] = [1,2];
console.log(a,b); //1,2
- 变量交换
let a = 1;
let b = 2;
[a,b] = [b,a];
console.log(a,b); //2,1
- 默认值
let [a,b,c,d] = [1,2,3];
console.log(a,b,c,d); //1,2,3,undefined
- 嵌套数组结构
let [a,b,c,d] = [1,2,[3,42]];
console.log(a,b,c,d); //1,2,[3,42]
- 不定元素
let [a,...arg] = [1,2,3,4];
console.log(a,arg); //1,[2,3,4]
- 数组复制
let arr = [1,2];
let arr2 = [3,4];
let arr3 = [...arr,...arr2];
console.log(arr3);
3:函数解构赋值
function fn(a,{username,age},b) {
console.log(a,username,age,b);
}
fn(1,{username:'zs',age:10},2); //1,zs,10,2
fn(1,2,{username:'zs',age:10});
//1 undefined undefined {username: 'zhang', age: 12}
- 如果调用函数时不提供被解构的参数会导致抛出错误
function fn(a,b) {}
fn();
//TypeError: Cannot destructure property 'a' of 'undefined' as it is undefined.
function fn([a,b]) {}
fn();
//TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator))
- 可以为解构参数指定默认值
function fn({a=1,b=1}={}) {
console.log(a,b)
}
fn()//1,1
- 解构返回结果
function fn() {
return {
data: '返回结果'
}
}
let {data} = fn();
console.log(data); //返回结果
4 :字符串解构
let str = 'abcde';
let [a,b,c] = str;
consloe.log(a,b,c);
5:数值和布尔值解构
- 解构赋值时,如果等号右边是数值和布尔值,则会先转化为对象
let {toString: s} = 123;
console.log(s === Number.prototype.toString); // true
let {toString: b} = true;
console.log(b === Boolean.prototype.toString); //true
三:字符串拓展
1:模板字符串
- 模板字符串(template string),是增强版的字符串,用反引号(`)标识,可以嵌套变量,可以换行,可以包含单引号和双引号。
let a = 'abc';
let str = `${a}`;
console.log(str); //abc
- 大括号中可以放任意js表达式,可以进行运算,调用函数,以及引用对象属性
let fn = function () {
return 1;
}
let arr = [1,2,3];
let str = `${fn()}+${arr[1] + arr[0]}`;
console.log(str); //1+3
2:字符串新增方法
- 去空格
trim():删除字符串两端空白符
trimStart():去除首部的空格
trimEnd():去除尾部的空格
- 判断
startsWith():判断开头有没有包含某个字符串
endsWith():判断结尾有没有包含某个字符串
includes():判断开头有没有包含某个字符串
let str = 'abcdefg';
console.log(str.startsWith('a')); //true
console.log(str.endsWith('a')); //false
console.log(str.includes('a')); //true
- repeat():重复当前字符串,指定次数
let str = 'abc';
console.log(str.repeat(2)); //abcabc
- 补充字符
padStrat():在前边补充任意字符,达到指定长度,第一个参数为指定长度,第二个参数为补充字符
padStrat():在后边补充任意字符,达到指定长度,第一个参数为指定长度,第二个参数为补充字符
let str = 'abc';
console.log(str.padStart(5,'o')); //ooabc
console.log(str.padEnd(5,'o')); //abcoo
四:spread运算符与rest参数
1:spread运算符
- 复制,合并数组
let arr = [1,2];
let arr1 = [...arr]; //[1,2]
console.log(arr1);
let arr2 = [3,4];
let arr3 = [...arr,...arr2];
console.log(arr3); //[1,2,3,4]
- 复制,合并对象
let obj = {
a: 1,
b: 2
};
let obj2 = {
...obj
};
console.log(obj2, obj2 === obj); //{a:1,b:2}
let obj3 = {
c: 3,
d: 4
};
let obj4 = {
...obj,
...obj3
};
console.log(obj4); //{a: 1, b: 2, c: 3, d: 4}
- 字符串转为数组
let str = 'wow';
let [...str1] = str;
console.log(str1); //['w', 'o', 'w']
- 伪数组转为真数组
function fn() {
let [...arg] = arguments;
console.log(arg);
}
fn(1,2,3,4) //[1, 2, 3, 4]
2:rest参数
- 获取函数调用时传入的参数
function fn(...arg) {
console.log(arg);
}
fn(1,2,3,4); //[1,2,3,4]
- 和普通函数混合使用时,需要放在参数后面
function fn(a,...arg) {
console.log(arg);
}
fn(1,2,3,4); //[2,3,4]
- 函数的length属性,不包含rest参数
function fn(a,b,c,...arg){};
console.log(fn.length); //3
五:数组的拓展
1:Array对象的新方法
- from:把伪数组转为数组(可以使用数组的方法)
function fn() {
console.log(Array.from(arguments));
}
fn(1,2,3); //[1,2,3]
- of:弥补构造函数Array()的不足,指定数组元素
console.log(Array()); //[]
console.log(Array(2)); //[empty × 2]
console.log(Array(1,2)); //[1, 2]
console.log(Array.of(2)); //[2]
2:Array原型上新增方法
- copyWithin():在当前数组内部,将指定位置的成员复制到其他位置(会覆盖原有成员),然后返回当前数组,保证数组长度不变
//它接三个参数:
//target:从该位置开始替换数据,如果为负值,表示倒数
//start:从该位置开始读取数据,默认值为0,负值为末尾开始计算
//end:到该位置前停止读取数据,默认为数组长度,负值为末尾开始计算
let arr = [1,2,3,4];
let arr2 = arr.copyWithin(1,0,3); //[1, 1, 2, 3]
- fill():使用固定值填充数组,数组中已有的元素,会被抹去
//可接受第二个和第三个参数,用于指定起始位置和结束位置
let arr = [1,2,3];
console.log(arr.fill('a')); //['a','a','a']
let arr = [1,2,3];
console.log(arr.fill('a',2,3)); //[1,2,'a']
- entries():对键值对的遍历,keys():对键名的遍历,values():对键值的遍历
let arr = [1,2,3];
for(let [key,values] of arr.entries()) {
console.log(key,values);
} //0 1 1 2 2 3
for(let key of arr.keys()){
console.log(key);
} //0,1,2
for(let values of arr.values()){
console.log(values);
}//1,2,3
- find():找出第一个符合条件的数组成员,findIndex():找出符合条件的第一个元素的下标,没有则得到-1
let arr = ['a','b','c'];
let res = arr.find(function (item) {
return item = 'a';
})
console.log(res); //a
let res1 = arr.findIndex(function (item) {
return item = 'a';
})
console.log(res1); //0
- includes():返回布尔值,表示某个数组中是否包含给定的值
let arr = [1,2,3];
console.log(arr.includes(1)); //true
- flat():将嵌套数组拉平,返回新数组,对原数组没有影响
let arr = [1,2,3,[4,5,[6,7]]]
console.log(arr.flat()); //[1,2,3,4,5[6,7]]
console.log(arr.flat(Infinity));//[1,2,3,4,5,6,7]
六:函数拓展
1:函数参数设置默认值
function fn(a=1) {
console.log(a);
}
fn(); //1
2:箭头函数
① 箭头函数
const fn = () =>{
}
//参数为一个参数时,且返回值为一条语句时
const fn1 = a => a;
当对参数进行解构时,括号不允许省略;
没有参数或者多个参数时,参数括号不能省略;
当函数体为多条语句时,花括号不能省略;
函数体内只有一行代码,该代码返回为对象,可用圆括号将其包裹
② 注意事项
- 箭头函数没有自己的this,箭头函数内部的this并不是调用时指向的对象,而是定义时指向的对象
- 箭头函数不能用于构造函数,不能使用new关键字调用
- 箭头函数没有arguments对象
- 箭头函数使用call,apply,bind无法改变this指向
七:对象的拓展
1:对象简写
//将变量的名字作为属性名,变量属性值作为属性值
function fn(username) {
var obj = {
username,
}
console.log(obj); //{username: 'zs'}
}
fn('zs');
function fn(username) {
var obj = {
[username]:'ll'
}
console.log(obj); //{zs: 'll'}
}
fn('zs');
2:属性名表达式
利用函数返回值作为属性名表达式
function fn() {
return 'foo';
}
const obj = {
[fn()]:10
}
console.log(obj); //{foo: 10}
3:对象新增方法
// Object.is():比较两个值是否相等
console.log(Object.is({},{})); //fasle
console.log(Object.is('foo','foo')); //true
console.log(Object.is(NaN,NaN)); //true
// Object.assign():对象的合并,将源对象复制到目标对象,返回目标对象
const target = {a:1,b:2};
const source = {c:1,d:2};
console.log(Object.assign(target,source));//{a: 1, b: 2, c: 1, d:2}
// Object.keys():返回一个成员是对象键名的数组
console.log(Object.keys({a:1,b:2})); //[a,b]
// Object.values():返回一个成员是对象键值的数组
console.log(Object.keys({a:1,b:2})); //[1,2]
// Object.entires():返回一个成员是对象键值对的数组
console.log(Object.entries({a:1,b:2})); // [[a:1],[b:2]]
八:Math的拓展
1:进制写法
二进制用ob表示;八进制用0o表示
2:新增方法
-
Math.pow():指数运算,表示一个值的n次方
-
Math.trunc():将数字的小数部分去掉,保留整数
-
Math.sign():判断一个数字的性质,正数为1,负数为-1,NaN为NaN
-
Math.sqrt():平方根
-
Math.cbrt():立方根
-
Math.hypot():求所有参数平方和的立方根
九:Number的扩展
1:新增方法
- Number.isFinite():用来检查一个数是否为有限值,返回值为布尔值,传入非数值,会返回false,Infinity会返回fasle
- Number.isNaN():判断是否为NaN,返回布尔值
- Number.isInteger():判断是否为整数
- Number.parseInt(str):将字符串转换为对应数值
十:新增数据类型
1:Symbol
原始数据类型,表示独一无二的值
const s1 = Symbol('i am symbol');
console.log(s1); //Symbol(i am symbol)
//用于对象属性名
const obj = {
a: 1,
[Symbol()]: 2
}
console.log(obj); //{a: 1, Symbol(): 2}
//对一无二
const s = Symbol();
const ss = Symbol();
console.log(s === ss); //false
//相等时
const s2 = Symbol.for();
const s3 = Symbol.for();
console.log(s2 === s3); //true
特点:
- Symbol中传入的字符串没有任何意义,只是用来描述
- Symbol不能使用New调用
- 不能用Number转换,不允许运算
- Symbol作为对象属性或方法时,需提前用变量存储,否则,无法访问该属性或方法
- 无法使用for in遍历,可用使用Object.getOwnPropertySymbols
const obj = {
a: 1,
[Symbol('s')]: 2,
[Symbol('ss')]: 3
}
console.log(Object.getOwnPropertySymbols(obj));
//[Symbol(s),Symbol(ss)]
2:BigInt
Javascript所有数字保存为64位浮点数,数值的精度只能到53个二进制位(相当于16个十进制),大于这个范围的数,无法精确表示。BigInt只表示整数,没有位数限制,任何位数的整数都可以精确表示
let numN = 123n;
console.log(typeof numN);// "bigint"
BigInt与普通整数是两种值,它们之间并不全等
let num = 10;
let numN = 10n;
console.log(num == numN); //true
console.log(num === numN); //false
十一:新增数据结构
1:Set
类似数组,但是成员都是唯一的,没有重复的值;接受一个数组,或者具有iterable接口的其他数据结构,作为参数,用来初始化
const s = new Set([1,2,3,4]);
console.log(s); //{1, 2, 3, 4}
属性方法:
- size:返回Set的长度
- add():添加某个值,返回Set结构本身
- delete:删除某个值,返回布尔值,表示是否删除成功
- has():返回布尔值,表示该值是否为Set的成员
- clear():清除所有成员
- keys():返回键名,Set结构没有键名,只有键值,或为同一值
- values():返回键值
- entries():返回键值对
- forEach():使用回调函数遍历
const s = new Set([1,2,3,4]);
console.log(s.entries());{1 => 1, 2 => 2, 3 => 3, 4 => 4}
2:Map
类似对象,也是键值对,但是键的范围更大
const s = new Map([
['a',1],
[100,2],
[{},3],
[[],4],
[true,5],
[undefined,6],
[null,7],
[Symbol(),8],
]);
console.log(s); //{'a' => 1, 100 => 2, {…} => 3, Array(0) => 4, true => 5, …}
属性方法:
- size:返回Map结构成员总数
- set():设置键名对应的键值,返回Map结构,如果键名已有,键值会被更新,否则就生成新键
- get():读取键名对应的键值,如果找不到,返回undefined
- has():返回一个布尔值,表示某个键是否在当前Map中
- delete:删除某个键,返回true
- clear():清除所有成员
- keys():返回键名
- values():返回键值
- entries():返回所有成员
- forEach():遍历Map
十二:iterator
遍历器(Iterator)是一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)
作用:一是为各种数据结构,提供一个统一的、简便的访问接口;二是使得数据结构的成员能够按某种次序排列;三是 ES6 创造了一种新的遍历命令for...of循环,Iterator 接口主要供for...of消费
- 只要一种数据结构具有了Symbol.interator属性,那么就认为是可以迭代的
//为对象类型添加迭代器
let obj = {
a: 1,
b: 2,
}
Object.prototype[Symbol.iterator] = function () {
let index = 0;
let arr = Object.values(this);
return {
next() {
return {
value: arr[index],
done: index++ >= arr.length
}
}
}
}
for(let value of obj) {
console.log(value);
} // 1,2
- ES6中部署了iterator接口的有:Array,Set,Map,String