Learn ES2015

时间:2021-06-09 21:51:23

折腾了大半年的项目,用的angular折腾快疯了。 总算有个小结了。正好闲下来为新的项目做准备,学点新的玩意玩玩,以往ES6都没用过,感觉被大部队甩好远了,抓紧跟上大部队的脚步...

1.利用let和const引入块级作用域

通过ES6中定义的let关键字可以形成仅作用于该块作用域的局部变量

for(let i=0;i<10;i++){
}
console.log(i);//输出ReferenceError(未定义)
console.log(a);//输出ReferenceError(未定义),let声明的变量不会变量提升,规范了代码先声明后使用。
let a =2;
let a=3;//error let申明的变量不能重复定义。

let类似const也能形成块作用域,不同点在于const声明的变量为常量,不可改变

if(true){
  const a =888;
  a = 222;//error. const 声明的变量是常量。不可被修改
}
console.log(a);//输出ReferenceError(未定义)。块级作用域、

//有一点要注意的是不能改变const类型变量存储的东西
const person = {};
person.nam = 'Fink';
person = {};//error

2.变量解析与赋值

var [a,b,c] = [1,2,3];

var arr  = [1,2,3];
var [a,b,c] = arr;

//数量不对应
let [a,b,c] = [1,2];
console.log(a);
console.log(b);
console.log(c); // undefined

//多层数组
let [a,[b,c],d] = [1,[2,3],4];
      1,2,3,4

//多层不对应
let [a,[b,c],d] = [1,[2],3];
console.log(a)
console.log(b)
console.log(c) //undefined
console.log(d) 

//对应值非数组
let [a,b,c] = 1;//error
let [a,b,c] = false;//error 等号右边必须是可遍历对象。

//了解映射的原理之后,一个很好的应用场景就是交换数值。
let [a,b] = [1,2];
[a,b] = [b,a]

//es6在映射赋值中还加入了默认值
let [a,b=2,c] = [1];
console.log(a);
console.log(b);
console.log(c); // undefined

//针对对象的映射赋值
var {a,b} = {a:'1',b:'2'};
console.log(a);
console.log(b);
根据key查找value

//掌握这种方法,可以简化很多操作。如获取一个对象的某些属性
var person = {
    name:'fink',
    'age':23,
    'sex':'male'
}
let {name,age,sex}  = person;
console.log(name+age+sex); // fink23male

3.增加了模板字符串

let myName = 'Fink';
document.getElementById("app").innerHTML = `wo name is ${myName}`;

//$(变量名) 不仅支持变量,还支持函数表达式
var result = `my name is ${(function(){return 'fink'})()}`;

4.数组的扩展

//1.Array.from();将伪数组对象转换为真正的数组
//什么是伪数组对象?具有数组的结构,但不是数组对象,不能使用数组的方法如forEach等

let arr1 = {
  'a': 1,
  'b': 2,
  'c': 3

};

function arr2(){
     let a2  = arguments;
}

let arr3 = document.querySelectAll('div');
//上面三个都是伪数组对象。
'forEach' in arr1;   //false
let arr = Array.from(arr1);// es5的写法: var arr = Array.slice.call(arr1);
'forEach' in arr1;   //true;返回值是boolean。

//2.Array.find();在数组中检索第一个匹配到的元素。
// find()参数为一个函数,设置查找条件

let arr = [1,3,5,7];
var result  = arr.find(function(value,index,arr){return value >4});

var result2  = arr.find(function(value,index,arr){return value >10});
console.log(result);
console.log(result2); // 没有找到的时候返回undefined
//findIndex()和find()类似,只不过是查找到的结果对应的下标

// 3. Array.fill();给定一个值来替换数组元素。
let arr = [1,2,3,4,5];
arr.fill(5); //[5,5,5,5,5];
// fill 也可以接收三个参数,第二个和第三个参数分别为开始个结束的位置

let arr2 = [1,2,3,4,5,6,7];
arr.fill(5,1,3);//[1,5,5,4,5,6,7];

 5.函数增加默认参数。

function show(name,age=23){
   console.log(name+","+age)
}
show('fink'); // fink,23

 6.函数新增rest参数(...)。为了不需要使用arguments对象。

function f(v,...vals){
  console.log(v);
  console.log(vals);
}
f('fink',1,2,3,4,5,6); //temp  1,2,3,4,5,6

//可以看成将arguments转换为数组,要比arguments更灵活。

// ***需要注意的一点。
function f(...vals,v){}//这种方式会报错,rest参数后不能再加别的参数

除了在函数中作为rest参数,“ ... ”本身可以作为一个运算符使用,用处与rest参数刚好相反,是将一个数组转为用逗号分隔的参数序列,看看栗子:

function add(x,y){ return x + y; }
var arr = [23,12]; add(...arr); //35
Math.max(...[4, 13, 15]) // 等同于Math.max(4, 13, 15);
//结合rest使用 function f(...vals){ vals //[1,2,3] } var arr = [1,2,3]; f(...arr); //当然上面这样用是多次一举,转换为参数再转回来,目的是为了理解两者是互为逆操作的
//其它用法 var nodeList = document.querySelectorAll('div');
var array = [...nodeList];
var arr1 = [1,2,3],arr2 = [4,5,6];
var arr3 = [...arr1,...arr2]; //合并数组,在ES5中我们一般是这样用的arr1.concat(arr2);

 7.=>箭头函数

var f = a =>b
//a为参数,b为返回值

//当传入多个参数或对象时,要用()包裹
var add = (a,b) => a + b

//传入对象
    var plus = ({name,age}) => name + age;
    var person = {
        name:'Vicfeel',
        age:23
    };
    plus(person); //Vicfeel23

//this对象的指向是可变的,但是在箭头函数中,它是固定的

var show  = {
   init : function(){
      document.addEventListener('click',e = >this.doThing(e),false);
   }
    ,
  dothing: function(e){
   console.log('do something')
}

}     

8.第七种数据类型。Symbol();

该类型通过 Symbol()来创建。(不能使用new)。表示独一无二的。

9.新的数据结构Set

Set数据结构和数组类似,区别在于Set内元素是唯一不重复的,Set函数可以接受一个数组(或类似数组的对象)作为参数,用来初始化,可以通过add方法添加元素

   //ES6环境下

   //Set的方法
   //Set - 构造函数,参数为一个数组
   let arr = [1,2,3,3,4,4];
   let s = new Set(arr);//Set{1,2,3,4}

   //add - 添加一个值,返回结构本身
   s.add(5); //Set{1,2,3,4,5}
   s.add(2); //Set{1,2,3,4,5}
   s.add(6).add(7);//Set{1,2,3,4,5,6,7}

   //delete - 删除一个值,返回一个布尔值表明删除是否成功
   s.delete(6); //true,Set{1,2,3,4,5,7}

   //has - 判断是否包含该值,返回一个布尔值
   let ok = s.has(6);//false,Set{1,2,3,4,5,7}

   //clear - 清空Set
   s.clear();//Set{}

   //Set的属性
   s.size; //0,与数组不同set通过size获取大小
   s.add(5);
   s.size; 

Set内元素具有唯一性,因此最直观的用途便是数组去重,现在我们可以这样实现数组去重:

 function unique(arr){
        return [...new Set(arr)]; //...运算符参看ES6系列(二)

        //或者 return Array.from(new Set(arr));
    }

 10.新数据结构Map

map一词本身就有映射的意思,Map数据结构提供了一种完善的键值对结构,之所以称之为完善是相对于之前而言,我们知道JS中的对象Object本身就是一种键值对hash结构,然而这种键值对确是不完善的。

Object中只能将字符串作为键,无法使用对象作为键,Map数据结构的提出就是为了解决这个问题

//来看一下Map数据结构的基础用法:
    //构造函数
    var m = new Map();
    var p = {name:'vicfeel'};
    //添加键值对
    m.set(p,'val');
    //获取键值对
    m.get(p); //"val"
    m.get('name'); //undefined
    //返回大小
    m.size;
    //重复添加相同键会覆盖先前的
    m.set(p,'newVal');
    m.get(p); //"newVal"

    //利用包含键值对的数组初始化Map,相同键后面也会覆盖前面
    var arr = [{'name':'vicfeel'},{'age':23},{'age':25}];
    var m2 = new Map(arr);
    m2.get('age'); 

    //判断是否含有某个键
    m2.has('name');  //true
    //删除某个键
    m2.delete('name');
    m2.has('name'); //false

    //清空
    m2.clear();
    m2.size; 

另外,另外Map数据结构也有一个forEach方法用于遍历:

    let m = new Map();
    m.set('name','vicfeel').set('age',25);
    m.forEach(function(val,key,map){
        console.log("Key: %s, Value: %s", key, val);
        //Key: name, Value: vicfeel
        //Key: age, Value: 25
    });

 11.Iterator(遍历器)

ES新提供的遍历方法for...of的遍历方式便是自动寻找该对象的Iterator接口,一些数据结构是默认部署Iterator接口的,包括数组、Set和Map结构、伪数组(比如arguments对象、DOM NodeList对象)、后文的Generator对象,以及字符串,因此这些数据结构是可以直接使用for...of进行遍历的