Published on

ES6基础回顾

Authors

ECMAScript和JavaScript的关系是,前者是后者的规格,后者是前者的一种实现

解构赋值

等号的右边必须是数组、对象、Set、Map等可遍历的数据结构(具备Iterator接口)

数组的解构赋值
let [a, b, c] = new Set([1, 2]);
let [a, b,c] = [1, 2];
// a = 1   b = 2 c = undefined 

let [a, b, c = 8] = new Set([1, 2]);
// a = 1   b = 2 c = 8

对象的结构赋值

解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象. 对象的解构赋值的内部机制是先找到同名属性,然后再赋值给对应的变量。真正被赋值的是后者,而不是前者.

let { a = 0, b, c = 4, d: v ,e} = { a: 1, b: 2, d: 5 };
// a = 1   b = 2   c = 4   v = 5  e = undefined
String.fromCodePoint()

ES5提供了String.fromCharCode方法,用于从码点返回对应字符,但是这个方法不能识别32位的UTF-16字符(Unicode编号大于OxFFFF)。

at()

ES5对字符串对象提供了charAt方法,返回字符串给定位置的字符。该方法不能识别码点大于OxFFFF的字符。

标签模板

模板字符串紧跟在一个函数名后面,该函数将被调用来处理这个模板字符串。这被称为“标签模板”功能。

其他方法
  • inclues() : 返回布尔值,表示是否找到了参数字符串。
  • startsWith() : 返回布尔值,表示参数字符串是否在源字符串的头部。
  • endsWith() : 返回布尔值,表示参数字符串是否在源字符串的尾部。
  • padStart() : 用于头部补全
  • padEnd() : 用于尾部补全

数值扩展

进制转换
0X1E.toString(8); // 36  --> 十六进制转换为八进制

let sum = 455;
sum.toString(16) // 1C7  --> 十进制转换为十六进制
Number.isFinite():判断值是否为有限
Number.isFinite(0);  // true
Number.isFinite(NaN);  // false
Number.isFinite(true);  // false
Number.isFinite(Infinity);  // false
Number.isFinite(-Infinity);  // false
Number.isNaN():判断是否NaN
Number.isNaN(true);  // false
Number.isNaN(Number('1'));  // true
Number.isNaN(Number('E'));  // false
Number.parseInt()、Number.parseFloat()

与全局方法使用一致

Number.islnteger():判断一个数是否是整数
Number.isInteger(true); // false 

Number.isInteger(25.0); // true

Number.isInteger("25"); // false
Number.isSafelnteger()

JavaScript能够准确表示的整数范围在-2^53到2^53之间(不含两个端点),超过这个范围就无法精确表示。

Number.isSafeInteger(Math.pow(2,52)); // true

Number.isSafeInteger(Math.pow(2,53)); // false
Math对象扩展函数
  • Math.trunc():去除一个数的小数部分,返回整数部分
Math.trunc(23.89); // 23
  • Math.sign():判断-个数到底是正数、负数,还是零
    • 参数为正数,返回+l;
    • 参数为负数,返回-1
    • 参数为0,返回0
    • 参数为-0,返回-0
    • 其他值,返回NaN
Math.sign(0); // 0
Math.sign('2'); // 1
Math.sign('E'); // NaN
  • Math.fround():返回一个数的单精度浮点数形式
Math.fround(1.337); // 1.3370000123977661
指数运算符(**)
2**3; // 8 即2的3次方

函数的扩展

函数默认值与解构赋值配合
function SubEvent({ name = '', age: year = 12,color = 'blue' },attribute = true) {
  // 得到 name='test' ; year=18 ; color='blue'; attribute=true
  .......
}

SubEvent({ name: 'test', age: 18 });
rest参数
function SubEvent(...params) {
  console.log(params);  // [{ name: 'test', age: 18 }]
}

SubEvent({ name: 'test', age: 18 });
箭头函数

函数体内的this对象就是定义时所在的对象,而不是使用时所在的对象 箭头函数不可以当作构造函数。也就是说,不可以使用new命令,否则会抛出一个错误 且不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用rest参数代替

let parm = () => 4;

let parm2 = () => ({ a: 1, b: 2 });

let parm3 = () => {
    return Math.trunc(23.78);
};

[1, 2, 3].map((res) => res * 2);

[1, 2, 3].filter((res) => res > 2);

数组的扩展

扩展运算待(...)

将一个数组转为用逗号分隔的参数序列

let params = [2, 3, 4];
console.log(...params);

function EsEvent([a, b, c]) { //解构赋值
  console.log(a, b, c); // 2 3 4
}

function EsEvent2(...parm) { // rest参数
   console.log(parm); //  [2,3,4]
}

EsEvent(...params);
EsEvent2(...params);
// 数组合并
let a = [2, 3];
console.log([0, 1, ...a]); // [0,1,2,3]

// 对象合并
let b = { c: 3, d: 4 };
console.log({ a: 1, b: 2, ...b }); // {a:1,b:2,c:3,d:4}

// 伪数组转换为数组
[...document.querySelectorAll('._value')]; // HTMLCollection集合转换为数组
[...new Set([...a, 4, 5, ...[2, 4]])]; // Set转为数组格式 去重  [2,3,4,5]
// 函数返回值(数组)
function GetParams() {
   let a = [2, 3, 4];
   return [...a];
}

const [aa, bb, cc = 9] = GetParams();
console.log(aa, bb, cc); // 2 3 4


// 函数返回值(对象)
function GetParams2() {
  let as = { m: 1, n: 2 };
  return { ...as };
}
const { m, n = 3 } = GetParams2();
console.log(m, n); // 1 2
Array.from():将两类对象转为真正的数组

类似数组的对象和可遍历(iterable)对象(包括ES6新增的数据结构Set和Map)

Array.from(new Set([1,2,3]));
效果等同于
[...new Set[1,2,3]];
Array.of():将一组值转换为数组。
Array.of(3, 11, 8); // [3,11,8]
Array.Prototype.find():找出第一个符合条件的数组成员
[2,3,4,5].find((value,index)=>{return index>1})   // 4

[2,3,4,5].filter((value,index)=>{return index>1})   // [4,5]
数组的空位
Array(3); // length属性为3  [ , , ]

对象的扩展

Object.keys()、Object.values()、Object.entries()
let aa = { a: 1, b: 2 };
let bb="c";

// Object.keys()
Object.keys(aa); // ['a','b']

// Object.values()
Object.values(aa); // [1,2]

// Object.entries()方法
Object.entries(aa).forEach(([key, value]) => {
   console.log(key, value); 
});

//变量名做属性
{
  ["d"+"d"]:4,
  foo:false,
  [bb]:3,
}
Object.is():比较两个值是否相等(严格相等)
Object.is(fasle,false); // true
Object.is('2',2); //fasle
Object.assign():将源对象(source)的所有可枚举属性复制到目标对象

Object.assign方法实行的是浅复制,而不是深复制。也就是说,如果源对象某个属性的值是对象,那么目标对象复制得到的是这个对象的引用。

let a1={a:1,b:{c:1}};
let a2=Object.assign({},a1);
a1.b.d=2;
console.log(a2); // {a:1.b:{c:1,d:2}}

// 克隆对象
let vs = { a: 1, b: 2 };
Object.assign(Object.create(Object.getPrototypeOf(vs)), vs);
属性的可枚举性

对象的每一个属性都具有一个描述对象(Descriptor),用于控制该属性的行为. 一旦把属性的 configurable 设置为 false,就不能再把它变回可配置了。此时,再调用 Object.defineProperty()方法修改除 writable 之外的特性,都会导致错误。

let os = { a: 1, b: 2 };
Object.getOwnPropertyDescriptor(os, 'a'); // 描述对象
{
  // 可配置
  configurable: true,
  // 可枚举
  enumerable: true,
  // 值
  value: 1,
  // 可写
  writable: true
}

Object.getOwnPropertyDescriptors(os);// 获取所有属性的描述对象
{
    "a": {
        "value": 1,
        "writable": true,
        "enumerable": true,
        "configurable": true
    },
    "b": {
        "value": 2,
        "writable": true,
        "enumerable": true,
        "configurable": true
    }
}
属性的遍历
  • for...in循环:遍历对象自身和继承可枚举属性(不包含Symbol属性)

  • Object.keys(): 遍历对象自身的所有可枚举属性(不包含Symbol属性)

  • Reflect.OwnKeys(): 遍历对象自身的所有属性,不管是否可枚举和属性名是Symbol

  • Object.getOwnPropertyNames():遍历对象自身所有(不包含Symbol属性)属性,不管是否可以枚举

  • Object.getOwnPropertySymbols():遍历对象自身的所有Symbol属性

__proto__属性

__proto__属性(前后各两个下画线)用来读取或设置当前对象的prototype对象。

Object.prototype.attrs=123;
let os = new Object();
os.__proto__ == Object.getPrototypeOf(os); // true
Object.is(os.__proto__,Object.getPrototypeOf(os)); // true
Object.setPrototypeOf()

Object.setPrototypeOf方法的作用与proto相同,用来设置一个对象的prototype对象,返回参数对象本身。它是ES6正式推荐的设置原型对象的方法。

Object.getPrototypeOf()
let os = { a: 1, b: 2 };
Object.getPrototypeOf(os);
Object.keys()、Object.values()、Object.entries()
let os = { a: 1, b: 2 };
Object.keys(os); // ['a','b']
Object.values(os); // [1,2]
Object.entries(os); // [ ['a',1],['b',2]]

Object.entries(os).forEach(([key, value]) => {
  console.log(key, value);
});
对象的扩展运算待
let { a, b, ...z } = { a: 1, b: 2, c: 3, d: 4 }; // a=1   b=2  z={ c: 3, d: 4}
let c = { c: 5, ...z }; // { c: 3, d: 4 }
let d = { ...c, ...z }; // { c: 3, d: 4 }
传导运算符
let os = { a: 1, b: {c:3,d:4} };

os?.a; // 1
os?.['a']; // 1

Set Map

遍历方法:map.keys();map.values();map.entries();forEach();

Set

成员唯一,属于伪数组

  • add(param):添加元素
  • clear():清空Set
  • delete(): 清除某个元素
  • has(): 判断是否存在元素
  • size属性:元素个数
ler set = new Set([1,2,3,3]); //set.size =  3


Array.from(new Set([1,2,3,3])); length=3  
等同于
[...new Set([1,2,3,3])];  // length = 3

Map
let map = new Map();
map.set('a',1);
map.get('a'); // 1

Reflect

  • Reflect.has(): 判断对象内是否存在指定属性
let os = { a: 1, b: 2 };
Reflect.has(os, 'a');
'a' in os
  • Reflect.deleteProperty(): 删除对象某一属性
let os = { a: 1, b: 2 };
Reflect.deleteProperty(os, 'a');
delete os.a;
  • Reflect.getPrototypeOf(): 获取对象原型
let os = { a: 1, b: 2 };
Reflect.getPrototypeOf(os); // 读取对象的__proto__属性
  • Reflect.setPrototypeOf(): 设置原型
let os = { a: 1, b: 2 };
Reflect.setPrototypeOf(os, null);
  • Reflect.defineProperty(): 与Object.defineProperty作用相同
let os = { a: 1, b: 2 };
Object.defineProperty(os, 'a', {
  value: 3, // 值
  enumerable: true, // 可枚举性
  writable: true, // 可写性
  configurable: false, // 可配置性
});
  • Reflect.getOwnPrope时yDescriptor(): 获取对象的可描述对象与Object.getOwnPrope时yDescriptor()一致
let os = { a: 1, b: 2 };
Reflect.getOwnPropertyDescriptor(os, 'a');
{
  "value": 1,
  "writable": true,
  "enumerable": true,
  "configurable": true
}
  • Reflect.isExtensible():对象是否可扩展 与Object.isExtensible()一致
Object.isExtensible(os); // true
  • Reflect.ownKeys(): 遍历对象的自身所有属性,不管是否可枚举和是否Symbol属性

Promise

let data = new Promise((resolve, reject) => {
  $.ajax({
    url: 'https://jsonplaceholder.typicode.com/todos/1',
    dataType: 'json',
    async: false,
    success(res) {
      resolve(res);
    },
  });
})
  .then((result) => {
    return new Promise((resolve, reject) => {
      $.ajax({
        url: 'https://jsonplaceholder.typicode.com/todos/1',
        dataType: 'json',
        async: false,
        success(res) {
          resolve({ result, res });
        },
      });
    });
  })
  .catch((error) => {
    console.log(error);
  });

let data2 = Promise.resolve({ a: 1, b: 2 });

async函数

async函数返回一个Promise对象,可以使用then方法添加回调函数。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。

async function GetData() {
   let res1 = await data;
   let res2 = await data2;
   return { res1, res2 };
}

GetData().then((res) => {
  console.log(res);
});