ES6系列2--语法扩展

    科技2023-11-02  89

    1.剩余参数(…rest)

    作用:将一个不定数量的参数表示为一个数组(旨在取代arguments)

    首先,我们看看arguments function show(){ return arguments; } console.log(show(1,2,3,4));// [Arguments] { '0': 1, '1': 2, '2': 3, '3': 4 } arguments是一个类数组对象,表示输入的所有实参,但没法直接使用Array的方法。 console.log(show(1,2,3,4).sort());// TypeError: show(...).sort is not a function 转换arguments为数组 // Array.from() console.log(Array.from(show(1,2,3,4)));// [1,2,3,4] // Array.prototype.slice.call() console.log(Array.prototype.slice.call(show(1,2,3,4)));// [1,2,3,4] 剩余参数居然是一个真正的数组,而且看起来作用和arguments一样,那有什么不同或者是改进呢?来看下一个例子 function show(a,...args){ return args; } console.log(show(1,2,3,4));// [2,3,4]

    估计大家都猜到了,剩余参数顾名思义就是剩下的参数,指没有对应形参的实参(也就是没显式命名的那些参数),上一个例子中…args对应的是后面三个参数

    同时,配合ES6的解构赋值可以方便取参 function show(a,...[b,c,d]){ return b + c + d; } console.log(show(1,2,3,4));// 9 总结: 剩余参数可以看做是arguments的升级版,直接返回一个数组,可以更方便使用数组的方法来操作参数。

    2.扩展运算符(…)

    原理:遍历数组或对象内的可枚举元素,并展开。

    展开字符串,返回数组 let arr1 = [...'hello']; console.log(arr1);// [ 'h', 'e', 'l', 'l', 'o' ] // 等价于 let arr2 = 'hello'.split(''); console.log(arr2);// [ 'h', 'e', 'l', 'l', 'o' ] 合并数组或对象 // 合并数组 let arr1 = [1,2,3]; let arr2 = [4,5,6]; console.log([...arr1,...arr2]);// [ 1, 2, 3, 4, 5, 6 ] // 等价于 console.log(arr1.concat(arr2));// [ 1, 2, 3, 4, 5, 6 ] // 合并对象 let obj1 = {name:'tom'}; let obj2 = {age:21}; console.log({...obj1,...obj2});// { name: 'tom', age: 21 } // 等价于 console.log(Object.assign(obj1,obj2));// { name: 'tom', age: 21 } 函数传参 function sum(a,b,c){ return a + b + c; } let arr = [1,2,3]; console.log(sum(...arr)); 解构赋值 let [first,...arr] = [1,2,3,4,5]; console.log(arr);// [2,3,4,5] 转Set结构为数组(用于数组去重) let arr = [1,2,2,'a','a']; let result = [...new Set(arr)]; console.log(result);// [ 1, 2, 'a' ] 替代apply let max1 = Math.max.apply(null,[1,2,3,4]); // 等价于 let max2 = Math.max(...[1,2,3,4]); // 等价于 let max3 = Math.max(1,2,3,4); console.log(max1);// 4 console.log(max2);// 4 console.log(max3);// 4

    3.ES6新增数据结构Set和Map

    Set

    S6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。Set本身是一个构造函数,用来生成 Set 数据结构。Set函数可以接受一个数组(或者具有 iterable 接口的其他数据结构)作为参数,用来初始化。

    // 例一 const set = new Set([1, 2, 3, 4, 4]); [...set] // [1, 2, 3, 4] // 例二 const items = new Set([1, 2, 3, 4, 5, 5, 5, 5]); items.size // 5 // 例三 const set = new Set(document.querySelectorAll('div')); set.size // 56 // 类似于 const set = new Set(); document .querySelectorAll('div') .forEach(div => set.add(div)); set.size // 56

    上面代码中,例一和例二都是Set函数接受数组作为参数,例三是接受类似数组的对象作为参数。 去除数组重复成员的方法:[…new Set(array)] 去除字符串里面的重复字符:[…new Set(‘ababbc’)].join(’’)

    Set实例的属性和方法

    属性:

    Set.prototype.constructor:构造函数,默认就是Set函数。Set.prototype.size:返回Set实例的成员总数。 实例的方法分为两大类:操作方法(用于操作数据)和遍历方法(用于遍历成员)。 操作方法:Set.prototype.add(value):添加某个值,返回 Set 结构本身。Set.prototype.delete(value):删除某个值,返回一个布尔值,表示删除是否成功。Set.prototype.has(value):返回一个布尔值,表示该值是否为Set的成员。Set.prototype.clear():清除所有成员,没有返回值。 const s = new Set(); s.add(1).add(2).add(2); // 注意2被加入了两次 s.size // 2 s.has(1) // true s.has(2) // true s.has(3) // false s.delete(2); s.has(2) // false

    遍历方法:

    Set.prototype.keys():返回键名的遍历器Set.prototype.values():返回键值的遍历器Set.prototype.entries():返回键值对的遍历器Set.prototype.forEach():使用回调函数遍历每个成员 let set = new Set(['red', 'green', 'blue']); for (let item of set.keys()) { console.log(item); } // red // green // blue for (let item of set.values()) { console.log(item); } // red // green // blue for (let item of set.entries()) { console.log(item); } // ["red", "red"] // ["green", "green"] // ["blue", "blue"]

    Map

    JavaScript 的对象(Object),本质上是键值对的集合(Hash 结构),但是传统上只能用字符串当作键。这给它的使用带来了很大的限制。为了解决这个问题,ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object 结构提供了“字符串—值”的对应,Map 结构提供了“值—值”的对应,是一种更完善的 Hash 结构实现。如果你需要“键值对”的数据结构,Map 比 Object 更合适。

    const m = new Map(); const o = {p: 'Hello World'}; m.set(o, 'content') m.get(o) // "content" m.has(o) // true m.delete(o) // true m.has(o) // false

    上面代码使用 Map 结构的set方法,将对象o当作m的一个键,然后又使用get方法读取这个键,接着使用delete方法删除了这个键。

    上面的例子展示了如何向 Map 添加成员。作为构造函数,Map 也可以接受一个数组作为参数。该数组的成员是一个个表示键值对的数组。

    const map = new Map([ ['name', '张三'], ['title', 'Author'] ]); map.size // 2 map.has('name') // true map.get('name') // "张三" map.has('title') // true map.get('title') // "Author"

    Map实例的属性和方法

    属性:

    size:返回 Map 结构的成员总数。

    操作方法:

    Map.prototype.set(key, value):set方法设置键名key对应的键值为value,然后返回整个 Map 结构。如果key已经有值,则键值会被更新,否则就新生成该键。Map.prototype.get(key):get方法读取key对应的键值,如果找不到key,返回undefined。Map.prototype.has(key):has方法返回一个布尔值,表示某个键是否在当前 Map 对象之中。Map.prototype.delete(key):delete方法删除某个键,返回true。如果删除失败,返回false。Map.prototype.clear():clear方法清除所有成员,没有返回值。

    遍历方法:

    Map.prototype.keys():返回键名的遍历器。Map.prototype.values():返回键值的遍历器。Map.prototype.entries():返回所有成员的遍历器。Map.prototype.forEach():遍历 Map 的所有成员。 需要特别注意的是,Map 的遍历顺序就是插入顺序。

    4.es6新增方法

    字符串新方法

    includes():返回布尔值,表示是否找到了参数字符串。startsWith():返回布尔值,表示参数字符串是否在源字符串的头部。endsWith():返回布尔值,表示参数字符串是否在源字符串的尾部。 var s = 'zfpx'; s.startsWith('z') // true s.endsWith('x') // true s.includes('p') // true repeat:repeat方法返回一个新字符串,表示将原字符串重复n次。

    数值的新方法

    Number.isNaN()用来检查一个值是否为NaN。 Number.isNaN(NaN) // true Number.isNaN(15) // false Number.isNaN('15') // false Number.isNaN(true) // false Number.isNaN(9/NaN) // true Number.isNaN('true' / 0) // true Number.isNaN('true' / 'true') // true Number.isInteger()用来判断一个数值是否为整数。 Number.isInteger(25) // true Number.isInteger(25.1) // false from:方法 用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象(包括 ES6 新增的数据结构 Set 和 Map)。 let arrayLike = { '0': 'a', '1': 'b', '2': 'c', length: 3 }; // ES5的写法 var arr1 = [].slice.call(arrayLike); // ['a', 'b', 'c'] // ES6的写法 let arr2 = Array.from(arrayLike); // ['a', 'b', 'c'] of:是为了将一组数值,转换为数组(弥补Array方法的不足) let arr1=Array.of(2,7,9); //输出[ 2, 7, 9 ] find和findIndex:查到对应的元素和索引 let arr = [1, 2 ,3, 3, 4, 5]; let find = arr.find((item, index, arr) => { return item === 3; }); let findIndex = arr.findIndex((item, index, arr) => { return item === 3; }); console.log(find, findIndex); fill :就是填充数组的意思 会更改原数组 Array.prototype.fill(value, start, end = this.length); let arr = [1, 2, 3, 4, 5, 6]; arr.fill('a', 1, 2); console.log(arr);

    ES6 提供三个新的方法——entries(),keys()和values()——用于遍历数组可以用for…of循环进行遍历,唯一的区别是keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历。

    for (let index of ['a', 'b'].keys()) { console.log(index); } // 0 // 1 for (let elem of ['a', 'b'].values()) { console.log(elem); } // 'a' // 'b' for (let [index, elem] of ['a', 'b'].entries()) { console.log(index, elem); } // 0 "a" // 1 "b"

    对象新方法

    Object.is对比两个值是否相等 相等运算符(==)和严格相等运算符(===)。它们都有缺点,前者会自动转换数据类型,后者的NaN不等于自身,以及+0等于-0。 console.log(Object.is(NaN,NaN)); 这个方法与'==='的行为基本一致 Object.assign把多个对象的属性复制到一个对象中,第一个参数是复制的对象,从第二个参数开始往后,都是复制的源对象 var nameObj = {name:'zfpx'}; var ageObj = {age:8}; var obj = {}; Object.assign(obj,nameObj,ageObj); console.log(obj); //克隆对象 function clone (obj) { return Object.assign({}, obj); } Object.setPrototypeOf将一个指定的对象的原型设置为另一个对象或者null var obj1 = {name:'zfpx1'}; var obj2 = {name:'zfpx2'}; var obj = {}; Object.setPrototypeOf(obj,obj1); console.log(obj.name); console.log(Object.getPrototypeOf(obj)); Object.setPrototypeOf(obj,obj2); console.log(obj.name); console.log(Object.getPrototypeOf(obj)); proto 直接在对象表达式中设置prototype var obj1 = {name:'zfpx1'}; var obj3 = { __proto__:obj1 } console.log(obj3.name); console.log(Object.getPrototypeOf(obj3)); super 通过super可以调用prototype上的属性或方法 let person ={ eat(){ return 'milk'; } } let student = { __proto__:person, eat(){ return super.eat()+' bread' } } console.log(student.eat()); Object.keys(),Object.values(),Object.entries()Object.keys() ES5 引入了Object.keys方法,返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键名 var obj = { foo: 'bar', baz: 42 }; Object.keys(obj) // ["foo", "baz"]

    ES2017 引入了跟Object.keys配套的Object.values和Object.entries,作为遍历一个对象的补充手段,供for…of循环使用。

    Object.entries会把对象转化为二维数组 let {keys, values, entries} = Object; let obj = { a: 1, b: 2, c: 3 }; for (let key of keys(obj)) { console.log(key); // 'a', 'b', 'c' } for (let value of values(obj)) { console.log(value); // 1, 2, 3 } for (let [key, value] of entries(obj)) { console.log([key, value]); // ['a', 1], ['b', 2], ['c', 3] }
    Processed: 0.011, SQL: 8