大前端

ECMAScript 新特性

2021-04-28  本文已影响0人  丽__

ECMAScript 通常看做javaScript的标准化规范,实际上JavaScript是ECMAScript的扩展语言,ECMAScript只是提供了最基本的语法,JavaScript在此基础之上升级扩展 JavaScript语言本身指的就是ECMAScript。
2015年开始ES保持每年一个版本的迭代。ES按照年份命名


image.png

重点介绍在ES5.1基础之上的变化,归为4类

ES2015
const arr =[100,200,300]
const [, , three] = arr
console.log(three);

//  ... 提取后面所有成员,只能在最后一个位置
const [foo,...rest] = arr
console.log(rest)
const obj = {name:'adb',age:18}
const {name} = obj
console.log(name);

//为了防止命名冲突  可以将name重命名  name:objName
const name = 'tom'
const {name:objName}=obj
console.log(objName);

//也可以添加默认值    name:objName = 'jack'
const name = 'tom'
const {name:objName = 'jack' }=obj
console.log(objName);
//可以换行
const str = `hello es2015
                  jkjkljl
                  jkjlk`

//可以加入变量表达式
const name = 'tom'
const msg = `hey,${name} --- ${1+2}-------${Math.random()}`
console.log(msg);
// console.log  标签函数  会打印出hello world
const str = console.log`hello world`


const name ='tom'
const gender = true 
function myTagFunc (strings,name,gender){
      console.log( strings,name,gender);
      const sex = gender ?'man':'woman'
      return  strings[0]+name+strings[1] +sex+strings[2]
}
const result = myTagFunc`hey,${name} is a ${gender}.`
console.log(result);
//对模板字符串进行加工
const message = 'Error:foo is not defined'
console.log(message.startsWith('Error));//true
console.log(message.endsWith('.));//true
console.log(message.includes('Error));//true
//旧的
function foo(enable){
  enable = enable===undefined ? true : enable
  console.log(enable)
}

//新    带有默认值的参数要放在最后
function foo(bar,enable = true){
  console.log(enable);
}

//旧
function foo(){
  console.log(arguments)
}

//新    ... 操作符只能出现在参数的最后一位,并且只能出现一次
function foo(...args){
  console.log(args);
}

foo(1,2,3,4,5)
//旧
const arr = ['foo','bar','baz']
console.log.apply(console,arr)

//新的
console.log(...arr);
//旧的
function inc(number){
  return number +1
}
//新的
const inc = n => n+1;
console.log(inc(100));


const arr =[1,2,3,4,5,6,7]
//旧
arr.filter(function(){
  return item%2
})

arr.filter(i+>i%2)
const person = {
  name:'tom'
 // sayHi:function(){
 //  console.log(`hi,my name is ${this.name}`);
 // }
    sayHi:()=>{
       console.log(`hi,my name is ${this.name}`);
    }
}

person.sayHi();
const bar = 34444

const obj = {
  foo:123,
  //bar:bar
  bar,
 // method1:function(){
 //  console.log('1111');
 // }
 method1(){
    console.log(111);
  }
   [Math.random()]:123;//现在可以用[ ] 来写
}

//obj[Math.radom()] = 123; 之前可以在外面动态添加Math.radom 的值
console.log(obj);
obj.method1()
const source1 ={
  a:123,
  b:123
}

const target = {
  a:456,
  c:456
}
//合并对象
const  resultObject.assign(target,source1)
console.log(target);
console.log(result === target); //后面对象的属性覆盖前面对象的属性   true

function func(obj){
  const funcObj = Object.assign({},obj)
  funcObj.name = 'func obj'
  console.log(funcObj);
}

const obj = {name:'global obj'}
func(obj)
console.log(obj);

console.log( 
  0==false,  //true
  0===false  //false
  +0 === -0  //true
  NaN ===NaN //false
  Object.is(+0,-0),//true
  Object.is(NaN,NaN),//true
 )


const person = {
  name:'zce',
  age:20
}

const personProxy = new Proxy(person,{
    get(target,property){
        return property in target ? target[property] : 'default
        console.log(target,property);    
    },
    set(target,property,value){
        if(property ==='age'){
            if(!Number.isInteger(value)){
              throw new TypeError(`${value} is not an int`)
            }
        }
        target[property] = value
     },
})
personProxy.age =100
personProxy.gender = true
console.log(personProxy.name);
console.log(personProxy.xxx);
//Proxy   对比 Object.defineProperty()
 
const person = {
  name:'zce',
  age:20
}

const personProxy = new Proxy(person,{
  deleteProperty(target,property){
      console.log('delete',property);
      delete target[property]
  }
})

delete personProxy.age
console.log(person);
image.png

Proxy 更好的支持数组对象的监视
** 如何使用Proxy对象监视数组**

const list = []
const listProxy =  new Proxy(list,{
    set(target,property,value){
      console.log('set',property,value);
      target[property] = value
      return true //表示设置成功
    }
})
 
listProxy.push(100)

Proxy是以非侵入的方式监管了对象的读写

const person = {}
Object.defineProperty(person,'name',{
  get(){
    console.log('name被访问');
    return person._name
  },
  set(value){
    console.log('name 被设置');
    person._name = value
  }
})

Object.defineProperty(person,'age',{
  get(){
    console.log('age被访问');
    return person._age
  },
  set(value){
    console.log('age被设置');
     person._age = value
  }
})

person.name = 'jack'

console.log(person.name)


//Proxy 方式更为合理
const person2 = {
  name:'zce'
  age:20,
}

const personProxy = new Proxy(person2,{
  get(target,property){
    return target[property]
  }
  set(target,property,value){
      target[property] = value
  }
})
personProxy.name = 'jack'
console.log(personProxy.name);
const obj = {
  foo:123,
  bar:456
}

const proxy = new Proxy(obj,{
    get(target,property){
        console.log('watch logic~');
        return Reflect.get(target.property)
    }
})
console.log(proxy.foo);

Reflect 最大的意义就是提供了一套用于操作对象的API

const obj = {
    name:'zce',
    age:18
}

console.log('name' in obj);
console.log(delect.obj['age']);
console.log(Object.keys(obj));

console.log(Reflect.has(obj,;'name'))
console.log(Reflect.deleteProperty(obj,'age))
console.log(Reflect.ownKeys(obj))
//class 关键词
function Person(name){
  this.name = name
}

Person.prototype.say = function(){
  console.log(`hi,my name is ${this.name}`);
}

class Person{
     constructor(name){
      this.name = name
    }
    say(){
       console.log(`hi,my name is ${this.name}`);
    }
}

const p = new Person('tom')
p.say();
class Person{
     constructor(name){
      this.name = name
    }
    say(){
       console.log(`hi,my name is ${this.name}`);
    }

    static creat(name){
        return new Person(name)
    }
}

const tom = Person.create('tom')
tom.say();
class Person{
     constructor(name){
      this.name = name
    }
    say(){
       console.log(`hi,my name is ${this.name}`);
    }
}

class Student extends Person{
  constructor(name,name){
     super(name);//相当于调用父类构造函数
      this.number = number
    }
    hello(){
        super.say();//x相当于调用父类的方法
        console.log(`my school Number is ${this.number}`);
    }
}

const s = new Student ('jack','100')
s.hello()
const s = new Set();

s.add(1).add(2).add(3).add(4)

console.log(s);

s.forEach(i => console.log(i))

for(let i of s){
  console.log(i);
}

console.log(s.size);//获取整个集合的长度
console.log(s.has(100));//判断是否包含某个特定的值
console.log(s.delect(3));//删除
s.clear();//清空
console.log(s);

const arr = [1,2,3,4,5,1,2,3]
const result = Array.from(new Set())
const result = [...new Set(arr)]
console.log(result);
const obj = {}
obj[true] = 'value'
obj[123] = 'value'
obj[{a:1}] = 'value'

console.log(obj);
//如果添加的键 不是一个字符串,内部会将这个键的toString结果作为键
console.log(obj['[object object]']);//value
const m = new Map()
const tom = { name:'tom' }
m.set(tom,90)
console.log(m); // Map { { name : 'tom' } => 90 }
console.log(m.get(tom));//90

m.has();//判断某个键是否存在
m.delete();//删除
m.clear();//清空


m.forEach((value,key)=>{
    console.log(value,key);
})
//map数据结构与对象最大的区别就是,map可以用任意类型作为键,对象上只能够使用字符串作为键
//Symbol 数据类型
// shared.js  -----------------------
const cache = {}

//a.js --------------------------------
cache['a_foo'] = Math.radom();

//b.js --------------------------------
cache[b_foo] = '123'
console.log(cache);


const s = Symbol()
console.log(s);
console.log(typeof s)

console.log(
    Symbol() === Symbol()
);

console.log(Symnbol('foo'));
console.log(Symnbol('foo1'));
console.log(Symnbol('foo3'));

const obj = {}
obj[Symbol()] = '123'
obj[Symbol()] = '456'
console.log(obj);

const obj = {
  [Symbol()]:123
}
console.log(obj);
//Symbol 可以避免对象属性名重复产生的问题,还可以借助这种类型的特点模拟实现对象的私有成员

//a.js------------------------------
const name = Symbol()
const person ={
    [name]:'zce',
    say(){
      console.log(this[name]);
    }
}

//b.js-------------
person.say()

//最主要的作用就是为对象添加独一无二的属性名, 截止到ES2019,一共定义了7中数据类型(Number、String、Boolean、undefined、object、Null,Symbol),未来还会有一种新的数据类型BigInt ,用于存放更长的数字,目前还处在stage-4阶段,标准化过后就是8种数据类型了

//Symbol 补充
console.log(
  Symbol() === Symbol();//false
  Symbol('foo') === Symbol('ff') ;//false
);

const s1 =Symbol.for('foo');
const s1 =Symbol.for('foo');
console.log(s1===s2);//true

console.log(
    Symbol.for(true) === Symbol.for('true');//true
);


console.log(Symbol.interator);
console.log(Symbol.hasInstance);

const obj ={
  [Symbol.toStringTag]:'xobject'
}
console.log(obj.toString);// [object Xobject]

const obj = {
    [Symbol()]:'symbol value',
    foo:'normal value'
}

for(var key in obj){
    console.log(key);//无法拿到Symbol类型的属性名
}

console.log(Object.keys(obj));//无法拿到Symbol类型的属性名
console.log(JSON.stringify(obj));//Symbol 类型也会被忽略掉

console.log(Object.getOwnPrpertySymbols(obj));//获取到的全是Symbol类型的属性名
//for...of 循环
for(const item of arr){
  console.log(item);
}

arr.forEach(item =>{
  console.log(item);
})
for(const item of arr){
  console.log(item);
  if(item>100){
      break;//可以跳出循环
  }
}

//arr.forEach();//不能跳出循环
//arr.some();  //返回true可以终止遍历
//arr.every(); //返回fale 可以终止遍历

const s = new Set(['foo','bar'])
for(const item of s){
    console.log(item);
}

const m = new Map();
m.set('foo','132')
m.set('bar','456')

for(const [key,value] of m){
    console.log(key,value);
}

const obj = {foo:123,bar:456}
for(const item of obj){
   console.log(item);
}
//迭代器Iterator
const set = new Set(['foo','bar',''baz])

const iterator = set[Symbol.iterator]()

console.log(iterator.nex());
console.log(iterator.nex());
console.log(iterator.nex());
console.log(iterator.nex());
console.log(iterator.nex());
const obj = {
  //可迭代接口Iterable:约定内部必须有一个用于返回迭代器的iterator 方法
    [Symbol.iterator]:function(){
        return:{
            //  迭代器方法iterator ,约定内部必须有一个用于迭代的next方法
            next:function(){
                  return :{
                      //迭代结果IterationResult,约定内部必须有一个value属性,用于表示当前被迭代的数据,值可以是任意类型,还要有一个done属性用来表示是否迭代完成 
                      value:'zce',
                       done:true
                  }
             }
        }
    }
}



const obj = {
    store:['foo','bar','baz']
    [Symbol.iterator]:function(){
        let index = 0;
        const self = this
        return:{
            next:function(){
                  const result = {
                      value:self.store[index],
                       done:index>=self.store.length
                  }
                  index++
                  return result
             }
        }
    }
}
for(const item of obj){
    console.log('循环体',item);
}
const todos ={
    life:['吃饭','睡觉','打豆豆'],
    learn:['语文','数学','英语'],
    work:['喝茶','工作'],

    each:function(callback){
        const all = [].concat(this.life,this.learn,this.work)
        for(const item of all){
            console.log(item);
        }
    },
    [Symbol.iterator]:function(){
        const all = [...this.life,...this.learn,...this.work]
        let index = 0;
        return{
            next:function(){
                return{
                    value:all[index],
                    done:index++>=all.length
                }
            }
        }
    },
}

todos.each(function(item){
    console.log(item);
})

console.log('-------------');
for(const item of todos){
    console.log(item);
}
// 对外提供统一遍历接口,让外部不用关心内部结构 
// 当前的each 只适用于当前的数据结构,
// ES2015 iterator是语言层面实现迭代器模式,它适用于任何数据结构
//   Generator 函数
// function* foo() {

//     console.log('sf');
//     return 100
// }

// const result = foo();
// console.log(result.next());

function* foo() {
    console.log('111');
    yield 100;
    console.log('222');
    yield 200;
    console.log('333');
    yield 300;
}

const generator = foo();
console.log(generator.next());
console.log(generator.next());
console.log(generator.next());
console.log(generator.next());
// Generator 应用
// 案例1:发号器
function* createIdMaker() {
    let id = 1
    while (true) {
        yield id++
    }
}
const idMaker = createIdMaker();
console.log(idMaker.next().value);
console.log(idMaker.next().value);
console.log(idMaker.next().value);


//优化
const todos = {
    life: ['吃饭', '睡觉', '打豆豆'],
    learn: ['语文', '数学', '英语'],
    work: ['喝茶', '工作'],
    [Symbol.iterator]: function* () {
        const all = [...this.life, ...this.learn, ...this.work]
        for (const item of all) {
            yield item
        }
    }
}

for (const item of todos) {
    console.log(item);
}
//Array.prototype.includes-------------
const arr = ['foo',1,NaN,false]
console.log(arr.indexOf('foo'));//找到对应的元素的下标,如果没有找到会返回-1
console.log(arr.indexOf('bar'));
console.log(arr.indexOf(NaN));//不能够用来查找数组中的NaN 

console.log(arr.includes('foo'));//includes返回true或者false,可以用来查找NaN
console.log(arr.includes(NaN))

//指数运算符-----------------------------
console.log(Math.pow(2,10));//1024
console.log(2 ** 10);//1024

const {
    Console
} = require("console");

// ES 2017
const obj = {
    foo: 'value1',
    bar: 'value2'
}

// Object.values----------------

console.log(Object.keys(obj)); //返回所有键组成的对象
console.log(Object.values(obj)); //返回所有值组成的对象

// Object.entries----------------
console.log(Object.entries(obj)); //返回所有键值对

for (const [key, value] of Object.entries(obj)) {
    console.log(key, value)
}

console.log(new Map(Object.entries(obj)));


// Object.getOwnPropertyDescriptors(获取对象中属性的完整的描述信息)----------------
const p1 = {
    firstName: 'xing',
    lastName: 'ming',
    get fullName() {
        return this.firstName + " " + this.lastName
    }
}

console.log(p1.fullName);

// const p2 = Object.assign({}, p1)
// p2.firstName = 'zce'
// console.log(p2);

const descriptors = Object.getOwnPropertyDescriptors(p1); //获取完整的描述信息
// console.log(descriptors);
const p2 = Object.defineProperties({}, descriptors)
p2.firstName = 'zce'
console.log(p2.fullName);


// String.prototype.padStart / String.prototype.padEnd   (字符串填充方法)----------------
const books = {
    html: 5,
    css: 16,
    javasctipt: 123
}

for (const [name, count] of Object.entries(books)) {
    console.log(name, count);
}

for (const [name, count] of Object.entries(books)) {
    console.log(`${name.padEnd(16,'-')} | ${count.toString().padStart(3,'0')}`)
}
// 在函数参数中添加尾逗号----------------
function foo(bar, baz, ) {

}
const arr = [
    100,
    200,
    300,
    400,
]

Async / Await Promist 的一种语法糖

上一篇 下一篇

猜你喜欢

热点阅读