ES6 核心内容学习总结

ECMAScript6的特点
ES6即ES2015增添了许多必要的特性,例如模块和类,块级作用域,常量与变量…还有很多便利的功能如:箭头的功能和简单的字符串拼接等。其实ES6的某些”新”的特点并不是真的新,只是试图简化语法,这样就无需使用老式的方法编写代码,让我们编程更容易。
浏览器的支持程度 http://kangax.github.io/compat-table/es6/,可以通过Babel转码器把ES6写的代码转成ES5的,就不用担心运行环境是否支持。
编写注意:
chrome下使用ES6为保证可以正常使用大部分语法,需要使用严格模式,即在js开始部分加上’use strict’;
在firefox下使用ES6为保证可以正常使用大部分语法,需要知道测试版本,即在script标签的type属性中加上“application/javascript;version=1.7”属性值。

1.let 声明变量的关键字
(1).在相同的作用域内,let不能重复声明一个变量(不同的作用域内除外)
(2).let声明的变量不会被预解析
(3).暂时性死区,变量在let声明前都不能访问,为了防止先调用后声明这个现象
(4).let声明的变量拥有块级作用域,块级作用域指的是一个大括号就是一个作用域,以后就不要写自执行函数了。

'use strict’
//es5:
console.log(a);      //undefined 
var a=12;
console.log(a);      //12

//es6:
console.log(b);      //报错  不能提前使用
let b=20;
let b=30;            //报错 不能重复声明一个变量
console.log(b);

//例:给一组li添加点击事件弹出其的索引值
'use strict’
//es5实现:
        var lis=document.querySelectorAll("li");
        for(var i=0;i<lis.length;i++){
            (function(i){
              lis[i].onclick=function(){
                  alert(i);
              }
            })(i);
        }
//ES6实现:
      for(let i=0;i<lis.length;i++){
         lis[i].onclick=function(){
            alert(i);
         }
      }

2.常量const
const:声明一个常量
(1).声明一个常量再修改会报错;
(2).只声明不赋值会报错;
(3).必须先声明再使用,不会被提前解析;
(4).不能重复声明;
注意:对象中的属性是可以修改的。

const str=‘David';
str=12;    //报错  声明后不能再修改

const b;      //报错  没有赋值

console.log(c);  //报错  没声明就用了
const c=20;
const c='David';    //报错  重复声明了

//声明一个对象后,可以对它里面的属性进行修改
const obj={
  name:'David'
};
obj.name='小王';
console.log(obj);

3.解构赋值
按照一定模式,从数组或者对象中把数据拿出来,对变量进行赋值
(1).数组解构赋值
等号左边和右边都必须是数组,数组的解构赋值要一一对应,否则结果为undefined
(2).对象解构赋值
等号左边和右边都必须是对象,名字(key)要一一对应,顺序不需要对应,否则结果为undefined

//数组解构赋值
var [a,b,c]=[1,2,3];
console.log(a,b,c);
//可以用来调换两个值
var n1=10;
var n2=15;
var [n1,n2]=[n2,n1];
console.log(n1,n2);

//也可以用来取函数的返回值
function fn(){
  return ['red','green','blue'];
}
var [d,e,f]=fn();
console.log(e);      //green

//对象解构赋值
var obj={
  name:'David',
  QQ:3569853,
  language:['css','html','js'],
  work:function(){
      console.log('js');
  }
};
var {name,work,QQ,age}=obj;
console.log(name,work,QQ,age);

4.字符串的扩展方法
(1). includes() 字符串是否包含某个字符,参数为一个字符,
(2). startsWith() 字符串的开始位置的字符是否是传入的参数,参数是一个字符串;
(3). endsWith() 字符串的结束位置的字符是否是传入的参数,参数是一个字符串;
(以上的几个方法返一个boolean值)
(4). repeat(num)复制字符串,参数为数字一定要为正数,表示复制次数;

var str='David';
console.log(str.includes('i'));          //true
console.log(str.includes('b'));          //false
console.log(str.startsWith('k'));    //true
console.log(str.endsWith('n'));          //true
console.log(str.repeat(2));          //DavidDavid

(5).模板字符串
模板字符串:字符串的拼接方式,用反撇号字符 ` 代替普通字符串的引号 ’ 或 ” 。
1.字符串需要用一对反引号包起来,它可以定义多行字符串,只用一对反引号
2.要拼进去的数据需要放在${}里面
3.大括号里还可以进行运算
4.大括号里还可以调用函数

var obj={
  title:'星期一',
  content:'今天要上班'
};
function fn(){
  return '我爱编程,编程让我快乐';
}
var text=document.getElementById('text');
//es5拼接方法
text.innerHTML='<h1>'+obj.title+'</h1><p>'+obj.content+fn()+'</p>';
//es6拼接方法
text.innerHTML=`<h1>${obj.title}</h1><p>${obj.content+fn()}</p>`;

5.Math对象的扩展方法
(1).Math.trunc(num) 去除小数部分,是直接把小数部分去掉
1.对于非数值,先调用Number方法把它转成数字
2.对于空值和无法转成数字的值,结果是NaN
(2).Math.sign(num) 判断一个数是正数还是负数还是0
1.参数为正数,返回1
2.参数为负数,返回-1
3.参数为0,返回0
4.参数为-0,返回-0
5.参数为其它值,返回NaN
(3).Math.hypot() 开平方,参数可以为多个,把所有的参数的平方加起来,然后再开平方

console.log(Math.trunc(12.74));      //12
console.log(Math.trunc(0.5));        //0
console.log(Math.trunc('36.01'));    //36
console.log(Math.trunc(‘David'));    //NaN

console.log(Math.sign(5));          //1
console.log(Math.sign(-5));         //-1
console.log(Math.sign(0));          //0
console.log(Math.sign(-0));         //-0
console.log(Math.sign('David'));   //NaN

console.log(Math.hypot(3));         //3
console.log(Math.hypot(3,4));       //5
console.log(Math.hypot(3,4,5));     //7.

6.数组:
(1).Array.from()把类数组转成真正的数组
任何有length属性的对象就可以用这个方法转真正的数组, 对象中的key必须是0开始的数字。
(2). […类数组] 它是一个扩展方法,在这里可以把类数组转成真正的数组。

var str=‘David';
var newStr=Array.from(str);
console.log(newStr);        //["D", "a", “v", "i", "d"]

//对象身上只要有length属性就可以调用Array.from()把对象转成数组,对象中的key必需是从0开始的数字才能转
var obj={
  0:'red',
  1:'green',
  2:'blue',
  3:'yellow',
  length:4
};
var obj2={
  1:'red',
  2:'green',
  3:'blue',
  4:'yellow',
  length:4
};
console.log(Array.from(obj)); //["red", "green", "blue", "yellow"]
console.log(Array.from(obj2));//[undefined, "red", "green", "blue"]

// 对于ajax交互时,提交对象时可以省略一部分代码;如
var form={name:"chenchen",password:"123",phone:'13100000000'};
// 提交时如下;
this.ajax.post("路径",{...form},res=>{
    console.log({...form})  // {name:"chenchen",password:"123",phone:'13100000000'}
})

(3).Array.of()数值转数组
(4).Array.includes(“z”,index),查找某个数据在数组中是否存在,返回boolean
(5).for of 循环,能够直接读取键值(for in 循环,能够直接读取键名)它不光可以遍历数组或者对象,只要有遍历接口的对象都可以用它
(6).keys() 存储了数组的所有键名
(7).values() 存储了数组的所有键值
(8).entries() 存储了数组的所有键值对

var color=['red','green','blue','yellow'];
 //for in
 for(var attr in color){
     console.log(attr); //0 1 2 3
 }
 //for of
 for(var value of color){
     console.log(value);    //red green blue yellow
 }
 //字符串也可以使用for of
 var str='David';
 for(var value of str){
     console.log(value);      //D a v i d
 }
//遍历keys
 for(var key of color.keys()){
     console.log(key);    //0 1 2 3
 }
// 遍历values
 for(var value of color.values()){
     console.log(value);      //red green blue yellow    提示一下,chrome还不支持
  }
 //遍历entries
  for(let [key,value] of color.entries()){
     console.log(key,value);    //0 "red"  1 "green" 2 "blue"      3 "yellow"
 }

7.函数参数默认值
参数变量是默认声明的,不能用let和const声明

function fn(a,b){
  b=b||'David';
  console.log(a,b);
}
fn('hello');        //hello David
fn('hello','moto');    //hello moto

//参数变量是默认声明的,不能用let或者const再次声明
function fn2(a=20,b=10){
  //console.log(a,b);      //20 10
  //let a=12;            //报错
  console.log(a+b);
}
fn2();      //30
fn2(23,45);      //68

8.reset参数#####
reset参数,…变量名
reset参数是一个数组,它的后面不能再有参数,不然会报错。
扩展方法 … :
(1).后面跟类数组,加中括号,返回真数组;
(2).后面跟真数组,不加中括号,返回普通集合;
作用:1.替代apply方法;
2.替代concat方法;
3.将字符串转为数组。

function fn(a,b,c,...values){
  console.log(values);
fn(1,2,3,4,5,6,78);

function fn2(...values/*,a*/){
  let sum=0;

  for(var val of values){
      sum+=val;
  }
  //console.log(a);    //报错 后面不能再跟参数
  console.log(sum);
}
fn2(1,2,3,4,5);      //15

//三个点的用法
var arr1=[12,34,5,28,97];
var divs=document.querySelectorAll("div");
console.log([...divs]);      //类数组转真数组  注意:类数组以及三个点需要放在一对中括号里面
console.log(...arr1);        //12 34 5 28 97,注意把数组转成集合数据,不用加中括号

//作用1:替代数组的apply方法,求最大值
console.log(Math.max(12,34,5,28,97));    //97

var arr2=[12,34,5,28,97];
//es5实现
console.log(Math.max.apply(null,arr2));      //97
//es6实现
console.log(Math.max(...arr2));            //97

//作用2:替代concat
var arr3=[1,2,3];
var arr4=['a','b','c’];
//es5实现:
//console.log(arr3.concat(arr4));    //[1, 2, 3, "a", "b", "c"]
//es6实现
arr3.push(...arr4);
console.log(arr3);    //[1, 2, 3, "a", "b", "c"]

//作用3:把字符串转成数组
var str='David';
console.log([...str]); //["D", "a", "v", "i", "d"]
  1. 箭头函数
    语法:
    (1).function用var、let、const来表示
    (2).参数要写在第一个等号后面
    1.如果没有参数,需要写一对空的小括号
    2.只有一个参数,那就直接写,不用加括号
    3.参数有多个,需要加一个小括号,参数用逗号隔开
    (3).函数的主体内容是放在箭头后面,如果语句只有一条,那就直接写。如果语句有多条,需要把它们放在一对大括号里
    注意:
    1.函数体内的this对象就是定义函数时所在的对象,不是调用函数时候的对象
    2.不能当作构造函数来用,不能使用new
    3.函数内不能使用arguments对象,如果要用的话就用reset参数来代替
//es5
function fn1(){
  console.log('David');
}
fn1();

//es6
var fn1=()=>console.log('David');
fn1();

let fn2=a=>console.log(a);
fn2('小王');          //小王

const fn.=(a,b)=>{
  let result=a+b;
  console.log(result);
}
fn3(1,2);    //3

var fn1= (...values)=>{
  console.log(this);
}
fn1(1,2,3);

10.属性名表达式
把表达式放在中括号里作为属性名

'use strict'
var name='abc';
let key='interest';
let obj={
  name:'David',
  [key]:'编程',
  ['show'](){
      console.log(this.name);
  }
}
console.log(obj);

11.Symbol
新增的第7种数据类型,表示独一无二,用来作为属性名,保证不会与其他的属性名冲突。
1.它是通过Symbol函数生成的;
2.它的前面不能加new,因为它生成的是一个原始类型的数据,不是对象。
3.它可以接收一个参数,为了便于区分,即使长得一样也不相同。
4.它不能与其他的值进行运算,没有隐式转换。
5.它的值可以被转换成布尔值 (都为true )或者字符串,不能转成数字。

let s=Symbol();
console.log(s);            //Symbol()
console.log(typeof s);    //symbol
//console.log(new Symbol());  //报错

var s1=Symbol('David');
var s2=Symbol('David');
console.log(s1,s2,s1==s2); //Symbol(David) Symbol(David) false

//console.log(s1+'大卫');  //报错

console.log(String(s1));      //Symbol(David)
console.log(Boolean(s1));  //true
//console.log(Number(s1));    //报错,不能转成数字

//用法
var mySymbol=Symbol('j');
var obj={
  [mySymbol]:'David'
}
console.log(obj);//Symbol(j): "David"

12.Set
新增数据结构,类似数组。所有数据都是唯一的,没有重复的值。它本身是个构造函数。
size 数据的长度
add()添加一个数据
delete()删除一个数据
has() 查找某条数据,返回一个boolean值
clear()删除所有数据

var set=new Set([1,3,4,5,4,3,2]);
set.add(6);
set.delete(1);
console.log(set.has(5));            //true
//set.clear();
console.log(set,set.size);      //Set {3, 4, 5, 2, 6} 5

var divs=document.querySelectorAll("div");
var set2=new Set(divs);
console.log(set2);

var set3=new Set(['red','green','blue','yellow']);
set3.forEach(function(value,key,set3){
     console.log(value,key,set3);
});

for(let [key,value] of set3.entries()){
      console.log(key,value)
}

13.Map
新增数据结构,Map接受一个数组作为构造函数的参数。该数组的成员是一个个表示键值对的数组。所有数据都是唯一的,没有重复的值。
size 数据的长度
set() 添加一条数据
delete() 删除一条数据
get() 获取一条数据
has() 查找某条数据,返回一个布尔值
clear() 删除所有数据

var map=new Map([['name','David'],['age',18],['age',20]]);
map.set('sex','男');
map.delete('sex');
console.log(map.get('name'));    //David
console.log(map.has('age'));        //true
map.clear();
console.log(map,map.size);      //Map {"name" => "David", "age" => 20}

var map2=new Map([['name',’David'],['age',20]]);
//遍历数据
for(let [key,value] of map2.entries()){
  console.log(key,value);
}

14.原型、构造函数
es5和es6写法

// es5
// 构造函数定义属性
function Per(name,age,job){
    this.name=name;
    this.age=age;
    this.job=job;
    this.friends=["aa","bb"];
} 
Per.prototype={
  // constructor属性指向的构造函数
  constructor:Per,
  // 原型对象定义的方法 
  sayName:function(){
    alert(this.name);
  }
}
// 一个新实例
var per1=new Per("nike",25,"teacher");
// 又一个新实例
var per2=new Per("luce",28,"tea");
per1.friends.push("cc");
//这时两个实例的数组friends是不一样的
//因为构造函数内的属性是属于每个新实例自己的独立的属性
//prototype中的属性和方法则是所有实例共享的
alert(per1.friends)//aa,bb,cc
alert(per2.friends)//aa,bb

//注意:每当访问对象的某个属性时,程序会先从实例对象里找,如果找不到再从对象指向的原型对象里找,也就是执行两次搜索

// es6
class Animal {
  constructor(){
    this.type = 'animal'
  }
  says(say){
    console.log(this.type + ' says ' + say)
  }
}
let animal = new Animal()
animal.says('hello') //animal says hello

// 首先用class定义了一个“类”,可以看到里面有一个constructor方法,这就是构造方法,而this关键字则代表实例对象。简单地说
// constructor内定义的方法和属性是每个实例对象自己的独立的
// constructor外定义的方法和属性则是所有实力对象都可以共享的


 // 继承es5
//Suaa构造函数自定义属性
function Suaa(){
  this.pro1=true;       
}
//Suaa构造函数添加原型对象方法    
Suaa.prototype.get1=function(){
  return this.pro1;
};
//Subb构造函数自定义属性
function Subb(){
  this.pro2=false;
}

//Subb继承Suaa
Subb.prototype=new Suaa();

//给Subb构造函数添加原型对象方法
Subb.prototype.get2=function(){
  return this.pro2;
}
//创建Subb()的实例
var ins=new Subb();
//因为继承了Suaa所以拥有了Suaa的所有实例属性与方法,同时还有了指向Suaa原型对象的指针,所以也就有了Suaa的原型对象get1()方法
//其中搜索过程为先搜索实例,然后搜索Subb的原型,最后搜索所继承的Suaa原型
alert(ins.get1()); //true


// es6
class Cat extends Animal {
    constructor(){
        super()
        this.type = 'cat'
    }
}
let cat = new Cat()
cat.says('hello') //cat says hello

//上面定义了一个Cat类,该类通过extends关键字,继承了Animal类的所有属性和方法。
//super关键字,它指代父类的实例(即父类的this对象)。子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工。如果不调用super方法,子类就得不到this对象。
//ES6的继承机制,实质是先创造父类的实例对象this(所以必须先调用super方法),然后再用子类的构造函数修改this。

15、Promise
构造函数,异步操作变同步

// Promise 等待
// resolve()代表成功的状态,reject()失败的状态
let p = new Promise((resolve,reject) => {
    setTimeout(() => {
        console.log(1);
        resolve() //只有变成成功的状态,then才会执行
    }, 2000);
})
p.then(function(){
    setTimeout(() => {
        console.log(2);
    }, 2000);
})

let p1 = new Promise((resolve,reject) => {
    setTimeout(() => {
        console.log(1);
        resolve()
    }, 2000);
})

let p2 = new Promise((resolve,reject) => {
    setTimeout(() => {
        console.log(2);
        resolve()
    }, 4000);
})
// 只有当p1,p2都为成功的时候才会执行.then
// 并且p1p2同时执行
// 当其中1个失败,立刻全部是失败
Promise.all([p1,p2]).then(() => {
    console.log(3)
},function() {
    console.log("失败")
})
// 1
// 2
// 3

16、Generator
异步处理(Promise)的升级版本(了解即可)
1.语法: 在普通的函数后面加上*
2.当遇上yield关键字的时候函数就会暂停执行
3.将函数结果保存在函数中,通过.next()让函数继续执行
手动控制next让函数什么时候继续往下执行

function* fn(){
    yield console.log(1);  // 什么都没有打印
    yield console.log(2);
}
let f = fn(); // 将函数结果保存在函数中
f.next(); // 1 通过.next()让函数继续执行  
f.next(); // 2

function* fn(){
    let a = yield 0;
    yield console.log(a);
}
console.log(fn.next());
console.log(fn.next(2));

17、async

 /*
    * 语法: 在函数前面加上关键字 async
    * await关键字后面必须是Promise对象
    * */
    let p1 = function (){
        return new Promise((resolve,reject) => {
            setTimeout(() => {
                console.log(1);
                resolve()
            },3000)
        });
    };
    let p2 = function (data){
        return new Promise((resolve,reject) => {
            setTimeout(() => {
                console.log(`${data}  这里是p2`);
                resolve(`已经全部完成`)
            },1000)
        });
    };
    /*
        当遇到await 自动执行关键字后面的Promise对象
        当Promise对象变为成功或失败 会自动继续执行下一个await后面的Promise
    * */
    async function fn(){
        // 只有在async函数里面才能使用await关键字
        //  Promise对象成功时返回数据 可以在await关键字前面定义一个变量来接收
        let pp1 = await p1();
        let pp2 = await p2(pp1);
        // 这里的return出去的东西是在.then里面接收
        return pp2
    }
    fn().then((data) => {
        console.log(data);
    });

18、class

/*
    * 定义构造函数的语法 class + 自定义的名字 {}
    * */
    /*function fn(){

    }*/
    //  上面的 等于  下面
    class Cat{
        // 构造函数本身
        constructor(name){
            this.name = name;
        }
        getname(){
            return this.name
        }
        // 如果是静态的方法 不用new 可以直接调用
        static getcolor(color){
            console.log(color);
        }
    }
    class Dog extends Cat{
        constructor(name){
            super(name);// super 父类本身 constructor
        }
        static getcolor(color){
            super.getcolor(color);
        }
    }
    /*let c = new Cat(`猫`);
    console.log(c.getname());*/
    //Cat.getcolor(`#fff`)
    let d = new Dog(`狗`);
    /*console.log(d.getname());*/
    //d.getcolor(`#000`)
    Dog.getcolor(`#ccc`) //要使用父类静态的方法,子类中也要定义成静态的方法

猜你喜欢

转载自blog.csdn.net/cxz792116/article/details/80034737
今日推荐