ES & next
发展历史
-
浏览器脚本:Javascript;
-
服务器脚本: PHP / ASP / JSP;
-
ECMAScript 是一个标准,Javascript 是标准的实现;
-
ECMAScript 是Javascript 的规格;
浏览器端对于语言特性的实现有一些滞后 浏览器在用户侧升级也有一些滞后
ECMAScript / Javascript => ES6
babel
-浏览器的版本和语言本身有差异,所以我们要对语言进行编译降级
babel 6
- ES 标准:
- stage 0 : strawman 只是一个想法;
- stage 1 : proposal 值得继续的提议;
- stage 2 : draft;
- stage 3 : candiate
- stage 4 : finished es2024 spec 加入下一年的spec
babel-preset-stage-2,babel-preset-2016
-es标准每年都会变,babel 6的问题
babel 7
preset-env: target:[]
- 根据用户的一些浏览器的特性,在运行时动态引入这些
polyfill(垫片);bundle size最小。 - polyfill 是一个概念:垫片,在一个只支持es5的浏览器中去运行es6
函数解析
new 一个箭头函数会怎样?
箭头函数不能作为构造函数
- 会报错,提示:function is not a constructor;
- babel编译时会把this转成(void 0);
哪些不能用箭头函数
- arguments
- yield
- 构造函数的原型方法上
模版字符串
const str1 = 'xiaoming';
const str2 = 'student'
console.log(`Hello
I am ${str1},I'm a ${str2}`)
数组和对象
数组的细节
const funGenerator = (num) => new Array(num).map(item => params =>
const funGenerator = (num) => Array.from(new Array(num)).map(item => params => console.log(params));
funGenerator(10).map((func,index) => func(index));
对象的细节
console.log(NaN === NaN); //false
console.log(Object.is(NaN,NaN)); //true
//ES next 采用了 SameValueZero() 的比较,是一个引擎内置的比较方法
console.log([NaN].indexOf(NaN)) //-1
console.log([NaN].includes(NaN)) //true SameValueZero
//Object.assign深拷贝还是浅拷贝
let dist = { foo: 'foo'};
let bar = { bar: {bar:'bar'} };
let baz = { baz:'baz' };
const res = Object.assign(dist,bar,baz);
bar.bar.bar = 'newbar';
baz.baz = 'newbaz';
console.log(res);//{foo:'foo',bar:{bar:'newbar'},baz:'baz'}
get / set
class Person {
constructor(){
}
_age = '';
get age(){
console.log(_age);
return '18'
}
set age(val){
this._age = val
}
}
const str = new Person();
str.age = 20; //20
console.log(str.age) //18
Proxy 天生的代理模式
const stu ={
age:20
}
const stuProxy =new Proxy(stu,{
get: function(target, propKey,receiver){
console.log(target, propKey)
return Reflect.get(target, propKey,receiver)
},
set:function(target, propKey,value,receiver){
console.log(target, propKey,value)
return Reflect.set(target, propKey,value,receiver)
},
})
如何实现断言函数
const assert = new Proxy({},{
set(target,warning,value){
if(!value){
console.warn(warning);
}
}
})
const name = 'xiaoming';
assert['is not xiaoming']=(name==='xiaohong')
receiver
const stu ={
age:20
}
const stuProxy =new Proxy(stu,{
get: function(target, propKey,receiver){
console.log(target, propKey)
return receiver
},
set:function(target, propKey,value,receiver){
console.log(target, propKey,value)
return Reflect.set(target, propKey,value,receiver)
},
})
//receiver 指向原始的读操作所在的那个对象,一般情况下就是Proxy实例
console.log(stu.age) //{age:20}
Reflect
- 将Object上一些明显属于语言内部的方法放到Reflect对象上,现在Object 和Reflect 一同部署;
- 修改某些Object 方法的返回结果,让其更合理;
Map Set WeakMap WeakSet
- Weak 表示作为唯一的部分,必须是一个对象;
- Weak 是一个弱引用,不用考虑GC;
迭代器 Iterator
- 迭代器是一个接口,为各种不同的数据提供统一的访问机制。任何数据结构只要部署了
Iterator接口,就可以完成遍历操作。- 本质就是一个指针
- 该接口主要供
for ... of消费
-原生具备 Iterator 的数据结构: Array Map Set String TypedArray arguments NodeList
Object.entries
//非generator
function entries(obj){
let arr = [];
for(let key of Object.keys(obj)){
arr.push([key,obj[key]])
}
return arr;
}
//generator
function *entries(obj){
for(let key of Object.keys(obj)){
yield [key,obj[key]];
}
}
Promise.allSettled
function allSettled(array){
if(!(array instanceof Arrya)){
return reject(new Error('not array'))
}
return new Promise((resolve,reject)=>{
const res = [];
let count = 0;
array.forEach((func,index)=>{
Promise.resolve(func).then(value =>{
res[index]={
status:'fulfilled',value
}
},(reason)=>{
count ++;
res[index]={
status:'rejected',reason
}
}).finally(()=>{
++count === array.length && resolve(res)
})
})
})
}