目录
8 举一些ES6对Function函数类型做的常用升级优化?
20 module、export、import是什么,有什么作用?
21 日常前端代码开发中,有哪些值得用ES6去改进的编程优化或者规范?
26 Object.is() 与原来的比较操作符 ===、== 的区别?
32 全局作用域中,用 const 和 let 声明的变量不在 window 上,那到底在哪里?如何去获取?
33 介绍下 Set、Map、WeakSet 和 WeakMap 的区别
34 Promise.all() 和 Promise.allSettled()的比较
ES2015特指在2015年发布的新一代JS语言标准,ES6泛指下一代JS语言标准,包含ES2015、ES2016、ES2017、ES2018等。现阶段在绝大部分场景下,ES2015默认等同ES6。ES5泛指上一代语言标准。ES2015可以理解为ES5和ES6的时间分界线
babel是一个ES6转码器,可以将ES6代码转为ES5代码,以便兼容那些还没支持ES6的平台
在
ES6之前,声明变量只能用var,var方式声明变量其实是很不合理的,准确的说,是因为ES5里面没有块级作用域是很不合理的。没有块级作用域回来带很多难以理解的问题,比如for循环var变量泄露,变量覆盖等问题。let声明的变量拥有自己的块级作用域,且修复了var声明变量带来的变量提升问题。
优化部分
ES6新增了字符串模板,在拼接大段字符串时,用反斜杠()`取代以往的字符串相加的形式,能保留所有空格和换行,使得字符串拼接看起来更加直观,更加优雅
升级部分
ES6在String原型上新增了includes()方法,用于取代传统的只能用indexOf查找包含字符的方法(indexOf返回-1表示没查到不如includes方法返回false更明确,语义更清晰), 此外还新增了startsWith(),endsWith(),padStart(),padEnd(),repeat()等方法,可方便的用于查找,补全字符串
优化部分
- 数组解构赋值。
ES6可以直接以let [a,b,c] = [1,2,3]形式进行变量赋值,在声明较多变量时,不用再写很多let(var),且映射关系清晰,且支持赋默认值 - 扩展运算符。
ES6新增的扩展运算符(...)(重要),可以轻松的实现数组和松散序列的相互转化,可以取代arguments对象和apply方法,轻松获取未知参数个数情况下的参数集合。(尤其是在ES5中,arguments并不是一个真正的数组,而是一个类数组的对象,但是扩展运算符的逆运算却可以返回一个真正的数组)。扩展运算符还可以轻松方便的实现数组的复制和解构赋值(let a = [2,3,4];let b = [...a])
升级部分
ES6在Array原型上新增了find()方法,用于取代传统的只能用indexOf查找包含数组项目的方法,且修复了indexOf查找不到NaN的bug([NaN].indexOf(NaN) === -1).此外还新增了copyWithin(),includes(),fill(),flat()等方法,可方便的用于字符串的查找,补全,转换等
优化部分
ES6在
Number原型上新增了isFinite(), isInteger(),isNaN()方法,用来取代传统的全局isFinite(),isNaN()方法检测数值是否有限、是否是NaN。ES5的isFinite(),isNaN()方法都会先将非数值类型的参数转化为Number类型再做判断,这其实是不合理的,最造成isNaN('NaN') === true的奇怪行为--'NaN'是一个字符串,但是isNaN却说这就是NaN。而Number.isFinite()和Number.isNaN()则不会有此类问题(Number.isNaN('NaN') === false)。(isFinite()同上)
升级部分
ES6在Math对象上新增了Math.cbrt(),trunc(),hypot()等等较多的科学计数法运算方法,可以更加全面的进行立方根、求和立方根等等科学计算
let a = 5;
//isFinite 判断是不是数字,如果是数字,就返回true,不是就返回false。
console.log(Number.isFinite(a)) // 结果 true
let bb = 452;
// isInteger 判断是不是整数,如果是整数就返回true,不是就false。
console.log(Number.isInteger(bb));
console.log(Number.isNaN('number'))
//主要用于检测是不是NaN,如果是NaN就返回true,不是就返回false。
//如果 x 是特殊的非数字值 NaN(或者能被转换为这样的值),返回的值就是 true。如果 x 是其他值,则返回 false。
// isNaN() 函数可用于判断其参数是否是 NaN,该值表示一个非法的数字(比如被 0 除后得到的结果)。
// 如果把 NaN 与任何值(包括其自身)相比得到的结果均是 false,所以要判断某个值是否是 NaN,不能使用 == 或 === 运算符。正因为如此,isNaN() 函数是必需的。
优化部分
对象属性变量式声明。
ES6可以直接以变量形式声明对象属性或者方法,。比传统的键值对形式声明更加简洁,更加方便,语义更加清晰
let [apple, orange] = ['red appe', 'yellow orange']
let myFruits = {
apple,
orange,
}
// let myFruits = {apple: 'red appe', orange: 'yellow orange'};
尤其在对象解构赋值(见优化部分b.)或者模块输出变量时,这种写法的好处体现的最为明显
let { keys, values, entries } = Object
let MyOwnMethods = {
keys,
values,
entries,
}
// let MyOwnMethods = {keys: keys, values: values, entries: entries}
可以看到属性变量式声明属性看起来更加简洁明了。方法也可以采用简洁写法
let es5Fun = {
method: function () {},
}
let es6Fun = {
method() {},
}
对象的解构赋值。 ES6 对象也可以像数组解构赋值那样,进行变量的解构赋值
let { apple, orange } = {
apple: 'red appe',
orange: 'yellow orange',
}
对象的扩展运算符(... )。 ES6对象的扩展运算符和数组扩展运算符用法本质上差别不大,毕竟数组也就是特殊的对象。对象的扩展运算符一个最常用也最好用的用处就在于可以轻松的取出一个目标对象内部全部或者部分的可遍历属性,从而进行对象的合并和分解
let { apple, orange, ...otherFruits } = {
apple: 'red apple',
orange: 'yellow orange',
grape: 'purple grape',
peach: 'sweet peach',
}
// otherFruits {grape: 'purple grape', peach: 'sweet peach'}
// 注意: 对象的扩展运算符用在解构赋值时,扩展运算符只能用在最有一个参数(otherFruits后面不能再跟其他参数)
let moreFruits = {
watermelon: 'nice watermelon',
}
let allFruits = {
apple,
orange,
...otherFruits,
...moreFruits,
}
super 关键字。ES6 在Class 类里新增了类似this 的关键字super 。同this 总是指向当前函数所在的对象不同,super 关键字总是指向当前函数所在对象的原型对象
升级部分
ES6在Object原型上新增了is()方法,做两个目标对象的相等比较,用来完善'==='方法。'==='方法中NaN === NaN //false其实是不合理的,Object.is修复了这个小bug。(Object.is(NaN, NaN) // true)
ES6在Object原型上新增了assign()方法,用于对象新增属性或者多个对象合并
const target = {
a: 1,
}
const source1 = {
b: 2,
}
const source2 = {
c: 3,
}
Object.assign(target, source1, source2)
target // {a:1, b:2, c:3}
注意 :
assign合并的对象target只能合并source1、source2中的自身属性,并不会合并source1、source2中的继承属性,也不会合并不可枚举的属性,且无法正确复制get和set属性(会直接执行get/set函数,取return的值)
ES6在Object原型上新增了getOwnPropertyDescriptors()方法,此方法增强了ES5中getOwnPropertyDescriptor()方法,可以获取指定对象所有自身属性的描述对象。结合defineProperties()方法,可以完美复制对象,包括复制get和set属性ES6在Object原型上新增了getPrototypeOf()和setPrototypeOf()方法,用来获取或设置当前对象的prototype对象。这个方法存在的意义在于,ES5中获取设置prototype对像是通过__proto__属性来实现的,然而__proto__属性并不是ES规范中的明文规定的属性,只是浏览器各大产商“私自”加上去的属性,只不过因为适用范围广而被默认使用了,再非浏览器环境中并不一定就可以使用,所以为了稳妥起见,获取或设置当前对象的prototype对象时,都应该采用ES6新增的标准用法ES6在Object原型上还新增了Object.keys(),Object.values(),Object.entries()方法,用来获取对象的所有键、所有值和所有键值对数组
// Object.keys
// 处理对象,返回可枚举的属性数组
let person={
name:'一只流浪的kk',
age:20,
eat:function(){}
}
console.log(Object.keys(person));// ['name','age','eat']
// 处理数组,返回索引值数组
let arr=[1,2,3,4,5];
console.log(Object.keys(arr));//['0','1','2','3','4','5']
// 处理字符串,返回索引值数组
let str='hello';
console.log(Object.keys(str));//['0','1','2','3','4']
// Object.values()
//返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历属性的键值
let obj = {
foo : "bar",
baz : 20
};
console.log(Object.values(obj)); // ["bar", 20]
// 返回数组的成员顺序,与属性的遍历部分介绍的排列规则一致
const obj = {100 : "a", 2 : "b", 7 : "c"};
console.log(Object.values(obj)); //["b", "c", "a"]
// Object.values()只会遍历对象自身的可遍历属性
const obj = Object.create({},{p : {value : 10}});
console.log(Object.values(obj));
console.log(Object.getOwnPropertyDescriptors(obj)); // []
Object.create方法的第二个参数添加的对象属性(属性p),如果不显式声明,默认是不可遍历的,因为p的属性描述对象的enumerable默认是false,Object.values不会返回这个属性。
因此只要把enumerable改成true,Object.values就会返回属性p的值。
const obj = Object.create({},{p:{ value : 10, enumerable : true, configurable : true, writable : true, }}) console.log(Object.values(obj)); //[10]
//Object.values会过滤属性名为 Symbol 值的属性
//如果Object.values方法的参数是一个字符串,会返回各个字符组成的一个数组。
Object.values({ [Symbol()]: 123, foo: 'abc' });
console.log(Object.values('foo')); //["f", "o", "o"]
// 如果参数不是对象,Object.values会先将其转为对象
console.log(Object.values(42)); // []
console.log(Object.values(true)); // []
console.log(Object.values(undefined)); //error
console.log(Object.values(null)); //error
Object.entries()
var obj = { foo: 'bar', baz: 42 };
console.log(Object.entries(obj));
//如果原对象的属性名是一个 Symbol 值,该属性会被省略
console.log(Object.entries({ [Symbol()]: 123, foo: 'abc' })); // [ [ 'foo', 'abc' ] ]
// 遍历对象的属性
let obj = {
one : 1,
two : 2,
}
for(let [k , v] of Object.entries(obj)){
console.log(`${JSON.stringify(k)} : ${JSON.stringify(v)}`);
}
// 将对象转为真正的Map结构
const obj = {foo : "bar", baz : 10};
const map = new Map(Object.entries(obj));
console.log(map);
// 实现Object.entries方法
const entries = (obj) => {
let result = [];
const objType = typeof(obj);
if(obj === undefined || obj === null){
throw new TypeError();
}
if(objType === "number" || objType === "boolean"){
return [];
}


1421

被折叠的 条评论
为什么被折叠?



