ES6 规范详情

122 阅读5分钟

deconstruction解构 - 解开对象结构

constant兆瓦= {
teacher:"yy",
leader:"yiyi"
};
//读取属性
const teacher = zhaowa.teacher;
const leader =  zhaowa.leader;

const {
teacher,
leader
} = zhaowa;
const arr = ['yy','yiyi','yiiy','yiiiy'];
const a = arr[0];
const a1 = arr[1];

const [a1,a2,a3,a4] = arr'

key 解构技巧

const zhaowa = {
teacher :{
name:'yy',
age:30
},
leaderL'yiy',
nameL'es6'
}

//别名
const :{
   teacher:{
      name,
      age
   },
   leader,
   name:className
} = zhaowa;

追问 解构使用场景

形参解构

const sum = arr =>{
    let res = 0;
    
    (arr||[]).forEach(each=>{
        res+= each;
    })
  }
  //解构 - 适用于确定项目数量下的运算优化
  const sum = ([a,b,c])=>{
      return a + b+ c;
  }

结合初始值

const course - ({teacher,leader,course='zhaowa'}) =>{
    //运算
}

course({
    teacher:'yy',
    leader:'yiyi',
    // course:'es6'
})

返回值

 const getCourse= {} ={
    return {
        teacher,
        leader
     }
   }
   const {teacher,leader} = getCourse();

变量交换

    let a = 1;
    let b = 2;
    [a,b] = [a,b];

JSON处理

//code判断
ajax.get().then)res =>{

   let code = res.code;
   if(code ===0 ){
       let data= res.data;
       let msg = res.msg;
     
       let{
           data,
           msg
       } = res;
   }
})

//json处理
const json = '{"teacher","yy","leader","yiy"}'
const obj = JSON.parse(json);

const {
   teacher,
   leader
} = JSON.parse(json);

const 标志常量

 const LMIT = 10;
 const OBJ_MAP = {
 A:'a',
 a:'A
 }
 CONST queue = [1,2,3,4,5]

1.不允许重复声明赋值

var arg1 = 'yy',
arg1 = 'es';
//es5中实现常量
Object.defineProperty(window,'arg2',{
   value:'yy';
   writable:false
})
//ES6
const arg3 = 'yy'
arg3 = 'es6'//NOk

2.快级作用域

if(true){
var arg1 = 'yy';
}
console.log(arg1);//yy
if(true){
const arg1 = 'yy';
}
console.log(arg1);//arg2 is not defined
// => 追问 变量提升
console.log(arg2); //undefined
var arg2 = 'yy'

console.log(arg3);//arg3 not defined
const arg3 = 'es6'

//=> 追问2 dead zone
if(true){
     console.log(arg4);
     const arg4 = 'yy';
}
//=> 块级内部  声明 => 赋值 => 使用


3. const or let

  // const 锁定的是门牌号
 const OBJ_MAP ={
     a:'A',
     A:'a'
 };
 OBJ_MAP.a ='C';
 
 const addr = {
 name,
 age,
 sex
 }
 let add1 = {
 name,
 age,
 sex
 }
 add1 ={};
 //解决引用类型内部熟悉需要固定
 //破局 - Object.freeze()
 Object.freeze(obj);
 const obj2 = {
     teacher:'yy',
     age:30,
     className:'es6',
   }
    Object.freeze(obj2);
    obj2.age = 20;//不能修改成功
    
    //进一步追问 => 关于层级
 const obj3 = {
     teacher:'yy',
     age:30,
     className:'es6'zhaowa:['es6','ts']
   }
    Object.freeze(obj3);
    obj3.zhaowa[0] = 'free';//可以修改成功
    //freeze 只能冻结根层,嵌套的引用类型无法完全冻结
    //手写
    Object.myDeepfreeze= obj => {
    Object.freeze(obj);
    (Object.keys(obj) || []).forEach(key =>{
           if(typeof obj[key]==='object'){
         Object.myDeepfreeze(obj[key]);
           }
        })
     }
    

arrow_function 箭头函数

//传统函数
function test(a,b) {
    return a + b;
}
//传统函数表达式
function test2 = function(a,b){
    return a + b
}

箭头函数的时代

  const test3 = {a,b} =>{
       return a + b;
  }
  const test4 =(a,b) => a + b;
  const test4 = x => x + 2;
  

上下文

const obj2 = {
    teacher:'yy',
    class:'es6',
    getTeacher:function(){
         return this.teacher;
    },
    getClass:() => {
         return this.class
    }
 }
  //箭头函数上下文

追问 箭头函数的场景

1.dom操作

const btn = document.querySelector('#btn');

btn.addEventListener('click',function(){
    this.style.color = '#fff';
})

2.类操作

//箭头函数无法构造类
function Obj(teacher,class){
      this.teacher = teacher;
      this.class = class;
    }

const Obj(teacher,class) =>{
      this.teacher = teacher;
      this.class = class;
    }
    
//箭头函数无法构造原型上的方法
Obj.prototype.learn = function() {
    console.log(this.teacher,this.leader);
}   

3. 参数

const test = teacher =>{
        console.log(arguments);
}

模板字符串

let `we are ${NAME} IN ${CITY} city`;

数组

  • forEach=> 遍历数组的每一项做取值or改值
  • map=> 定向取值 or 定向改值
  • filter => 过滤出复合条件的元素组成的数组
  • some/every => 用于拼装一个满足要求的数组列表
  • reduce 使用场景如下

reduce使用场景

1.数组求和

let arr1 = [1, 2, 3, 4, 5, 6, 7, 8];
const total1 = arr1.reduce((previousValue, currentValue) => {
  return previousValue + currentValue;
}, 0);
console.log(total1); // 36

2.数组对象求和

let arr2 = [{ x: 1 }, { x: 2 }, { x: 3 }];
const total2 = arr2.reduce((previousValue, currentValue) => {
  return previousValue + currentValue.x;
}, 0);
console.log(total2); // 6

3.二维数组转为一维数组(数组的扁平化)

let arr3 = [[0, 1], [2, 3], [4, 5]];
const flattened = arr3.reduce((previousValue, currentValue) => {
  return previousValue.concat(currentValue);
}, [])
console.log(flattened); // [0, 1, 2, 3, 4, 5]

4.计算数组元素出现的次数

let names = ['小猪课堂', '张三', '李四', '王五', '小猪课堂']
let countedNames = names.reduce(function (allNames, name) {
  // 判断当前数组元素是否出现过
  if (name in allNames) {
    allNames[name]++
  } else {
    allNames[name] = 1
  }
  return allNames
}, {})
console.log(countedNames); // {小猪课堂: 2, 张三: 1, 李四: 1, 王五: 1}

Proxy

let obj = {};
let _proxy = new Proxy(obj,{
    get (target,prop){
       return target[prop];
      }
   
    set(target,prop,val){
        if(typeof val === 'string'){
            target[prop] = val;
            return true;
        } else {
            return false;
        }
     }
  })

Reflect

let class = {
    name:'zhaowa',
    age:30,
    get teacher(){
        return this.name + this.age
     }
  }
   
 Refalct.get(class,'name');
 Refalct.get(class,age,20);
 Reflect.set(class,age, );

SET & MAP

//set与数组类似,所有成员唯一(去重) --- new Set()
  add()  delete() clear() forEach() size
  
  let arr = [1,2,2,3,4];
  let set = new Set(arr);
  //1
  let newArr = [...set]
  //2
  let newArr = Array.from(set);
  
  //map 与对象类似,key可以为各种类型的值(数组,对象,数字)
  set() get() delete() clear() forEach() keys() value() size
  

1.1symbol一些应用场景

场景1:使用Symbol来作为对象属性名(key)

const PROP_NAME = Symbol();
const PROP_AGE = Symbol();
let obj = {
[Symbol("name")]: "yd",
age: 6,
title: "symbol",
};
  • Symbol 类型的 key 是不能通过以下方法枚举的,它未被包含在对象自身的属性名集合(property names)
1.
Object.keys(obj); // ["age","title"]
2.
for (let p in obj) {
console.log(p); // 分别输出 “age” 和 “title”
}
3.
Object.getOwnPropertyNames(obj); // ["age","title"]
4.
JSON.stringify(obj); // {"age":6,"title":"symbol"}
  • 获取以 Symbol 方式定义的对象属性
1.使用ObjectAPI
Object.getOwnPropertySymbol(obj); // [Symbol(name)]
2.使用新增的的反射API
Reflect.ownKeys(obj); // [Symbol(name),"age","title"]

场景2:使用Symbol代替常量

const TYPE_AUDIO = Symbol();
const TYPE_VIDEO = Symbol();
const TYPE_IMAGE = Symbol();
function handleFileResource(resource) {
switch (resource.type) {

case TYPE_AUDIO:
   playAudio(resource);
break;

case TYPE_VIDEO:
   playVideo(resource);
break;

case TYPE_IMAGE:
   previewImage(resource);
break;

default:
   throw new Error("Unknown type of resource");
   }
}

场景3:使用Symbol定义类的私有属性/方法

  • a.js 中
const PASSWORD = Symbol();
class Login {
  constructor(userName, password) {
    this.userName = userName;
    this[PASSWORD] = password;
  }
  checkPassword(pwd) {
     return this[PASSWORD] === pwd;
  }
}
export default Login;
  • b.js中
import Login from "./a";
const login = new Login("admin", "123456");
login.checkPassword("admin"); // true
login.PASSWORD; // oh!no!
login[PASSWORD]; // oh!no!
login["PASSWORD"]; // oh!no!

由于 Symbol 常量 PASSWORD 被定义在 a.js 所在的模块中,外面的模块获取不到这个 Symbol,也不可能再创建一个一模一样的 Symbol 出来(因为 Symbol 是唯一的),因此这个 PASSWORD 的 Symbol 只能被限制在 a.js 内部使用,所以使用它来定义的类属性是没有办法被模块外访问到的,达到了一个私有化的效果。

1.2 注册和获取全局 Symbol

通常情况下,我们在一个浏览器窗口中(window),使用 Symbol()函数来定义 Symbol 实例就足够了。

但是,如果你的应用涉及到多个 window(最典型的就是页面中使用了),并需要这些 window 中使用的某些 Symbol 是同一个,那就不能使用Symbol()函数了,因为用它在不同 window 中创建的 Symbol 实例总是唯一的,而我们需要的是在所有这些 window 环境下保持一个共享的 Symbol。这种情况下,我们就需要使用另一个 API 来创建或获取 Symbol,那就是Symbol.for(key),key必须是字符串,如果不是则toString(),它可以注册或获取一个 window 间全局的 Symbol 实例:


let gs1 = Symbol.for("global_symbol"); // 注册一个全局Symbol
let gs2 = Symbol.for("global_symbol"); // 获取全局Symbol
gs1 === gs2; // true

这样一个 Symbol 不光在单个 window 中是唯一的,在多个相关 window 间也是唯一的了。

async 、 await、 generator、for of生成自动化迭代器 -- promise课