ES6语法

1.ES5和ES6声明变量的方式对比

ES5中声明变量:var

1可以重复声明
2无法限制修改
3没有块级作用域

ES6中声明变量:let const

let 不能重复声明,变量-可以修改, 块级作用域
const 不能重复声明,常量-不能修改, 块级作用域

对于块级作用域用什么好处,以下举一个例子
//在ES6中没有块级作用域的情况下,以下按钮点击任何一个按钮都只会弹出最后一位
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <script type="text/javascript">
            window.onload = function (){
                var aBtn = document.getElementsByTagName('input');
                for(var i=0;i<aBtn.length;i++){
                    aBtn[i].onclick = function(){
                        alert(i)
                    }
                }
            }
        </script>
    </head>
    <body>
        <input type="button" name="" id="" value="按钮1" />
        <input type="button" name="" id="" value="按钮2" />
        <input type="button" name="" id="" value="按钮3" />
    </body>
</html>
//在没有用ES6之前解决办法就是以下处理,利用函数作为一级作用域,不过就是有点麻烦
for(var i=0;i<aBtn.length;i++){
    (function(i){
        aBtn[i].onclick = function(){
            alert(i)
        };
    })(i);
}
//直接用let的就可以快速解决这类问题
for(let i=0;i<aBtn.length;i++){
    (function(i){
        aBtn[i].onclick = function(){
            alert(i)
        };
    })(i);
}

2.ES6 中箭头函数

ES6 中函数式声明方式被箭头函数 => 取代
箭头函数:使用 => 定义函数

1.如果只有一个参数,( )可以省
2.如果只有一个return,{ }可以省

//简写前
let show = (a) =>{
 return a*2;
};
alert(show(12));  //24
//简写后
let show = a => a*2;
alert(show(12));  //24
//两个参数时()不能省
let show = (a,b) => a+b;
alert(show(1,2));  //3

3.函数的参数

  • 参数的扩展/展开
  • 默认参数

参数扩展:

1.收集剩余参数

//*Rest Parameter必须是最后一个,也就是以下代码中的args参数
  function show(a,b,...args){
    alert(args);
  }
  show(12,14,1,2,3);  // a=12   b=14    args=1,2,3
//如果args不是在最后一个,会报错
  function show(a,b,...args,c){
    alert(args);
  }
  show(12,14,1,2,3);
//Uncaught SyntaxError: Rest parameter must be last formal parameter

2.展开数组
展开后的效果,跟直接把数组的内容写在这儿一样

    let arr1 = [1,2,3];
    console.log(arr1);  //[1, 2, 3]
    console.log(...arr1);  //1 2 3
        //也可以用在合并两个数组中
        let arr2 = [4,5,6];
        let arr = [...arr1,...arr2];
        console.log(arr);  //[1, 2, 3, 4, 5, 6]
        //函数中也可以使用
        function show(...args){
        fn(...args)
    }
    function fn(a,b){
        console.log(a+b);
    }
    show(1,2);  //3

注意,不可以用在赋值上,以下代码就是直接赋值就报以下错误
Uncaught SyntaxError: Unexpected token '...'

        let a;
    let arr = [1,2,3];
        a = ...arr;
        console.log(a);

默认参数:

就是有一默认值,可传可不传

$('#div').animate({width: '200px'});
$('#div').animate({width: ''200px},1000);

4.ES6 中解构赋值

  • 左右两边结构必须一样
  • 右边必须是个东西
  • 声明和赋值不能分开(必修在一句话里完成)
        let [a,b,c] = [1,2,3];
        console.log(a,b,c);  //1 2 3

        let {e,f,g} = {a:12, c:5, d:22};
        console.log(e,f,g);  //12 5 22

        let [{a1,a2},[n1,n2,n3],num,str] = [{a1:12,b1:5},[12,5,8],8,'kk'];
        console.log(a1,a2,n1,n2,n3,num,str);//12 5 12 5 8 8 "kk"

如果结构不一样无法赋值,会报错

    let [a,b] = {a:12,b"12};
    console.log(a,b);
    //Uncaught SyntaxError: Identifier 'a' has already been declared

如果声明跟赋值分开也一样无法赋值,会报错

    let [a,b];
    [a,b] = [12,22];
    console.log(a,b);
    //Uncaught SyntaxError: Identifier 'a' has already been declared

5.数组

  • map        映射   一个对一个
  • reduce    汇总   一堆出来一个
  • filter         过滤器
  • forEach   循环(迭代)

map

    let arr = [12,5,8];
    let result = arr.map(item => item*2)
    console.log(result);  //[24, 10, 16]
    
    let score = [19,85,59,99];
    let res = score.map(item => item>=60?'及格':'不及格');
    console.log(res);  //["不及格", "及格", "不及格", "及格"]

reduce

    let arr = [1,2,3,4];
    //tmp初始值, 或者计算结束后的返回值。
    //item 当前元素
    //当前元素的索引
    let result = arr.reduce((tmp,item,index) => {
      return tmp+item;
    })
    //一开始 tmp = arr[0] item = arr[1] index = 1
    //后面tmp 会等于最后运算的结构,比如代码中是执行tmp+item
    //所以第二次tmp = arr[0] + arr[1] = 3 item = arr[2] index = 2
    console.log(result);  //10

filter

    let arr = [1,2,3,4,5,6];
    let result = arr.filter(item => {
      if(item%3 == 0){
        return true;
      }else{
        return false;
      }
    })
    console.log(result); //[3, 6]

forEach

  let arr = [12,15,13,5];
  arr.forEach((item,index) => {
    console,log(item); //12 15 13 5
  })

6.字符串

  • 多了两个新发法
    startsWith
    endsWith
  • 字符串模板
    字符串连接
        i.直接把东西塞到字符串里面       ${东西}
        ii.可以折行
  //startsWith和endsWith用法
  let str = 'https://www.baidu.com';
  if(str.startsWith('https://')){
    console.log('yes') //yes
  }else{
    console.log('no');
  }
  
  let email = '1002111759@qq.com'
  if(email.endsWith('@qq.com')){
    console.log('yes');
  }else{
    console.log('no');
  }
  //字符串连接
  let title = '标题';
  let content '内容';
  let str = `<div>
    <h1>${title}</h1>
    <p>${content}</p>
    </div>`
  console.log(str);

7.ES6的面向对象

class关键字、构造器和类分开了
class里面直接加方法

首先先看一下老版的面向对象以及继承

  function User(name,pass){
    this.name = name;
    this.pass = pass;
  }
  User.prototype.showName = function (){
    console.log(this.name);
  }
  User.prototype.showPass = function (){
    console.log(this.pass);
  }
  var u1 = new User('kk','123456');
  u1.showName(); //kk
  u1.showPass(); //123456
  //老版继承
  function VipUser(name,pass,level){
    User.call(this,name,pass);
    this.level = level;
  }
  VipUser.prototype = new User();
  VipUser.prototype.constructor = VipUser;
  VipUser.prototype.showLevel = function (){
    console.log(this.level);
  }
  var v1 = new VipUser('Flipped','123456',3);
  v1.showName(); //Flipped
  v1.showPass(); //123456
  v1.showLevel(); //3

ES6面向对象新写法

  class User{
    constructor(name,pass){
      this.name = name;
      this.pass = pass;
    }
    showName(){
      console.log(this.name);
    }
    showPass(){
      console.log(this.pass)
    }
  }
  var u1 = new User('kk','123456');
  u1.showName(); //kk
  u1.showPass(); //123456

  //ES6继承
  class VipUser extends User{
    constructor(name,pass,level){
      //super指代了整个prototype或者__proto__指向的对象
      // 用在构造函数中,必须在使用this之前调用
      super(name,pass);
      this.level = level;
    }
    showLevel(){
      console.log(this.level);
    }
  }
  var v1 = new VipUser('Flipped','123456',3);
  v1.showName(); //Flipped
  v1.showPass(); //123456
  v1.showLevel(); //3

面向对象应用---React

没学过React可以跳过以下案例

React:
  • 组件化 -- class    一个组件就是一个class
  • JSX     JSX==babel==browser.js
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
                <script src="react.js" charset="utf-8"></script>
                <script src="react-dom.js" charset="utf-8"></script>
                <script src="browser.js" charset="utf-8"></script>
                <script type="text/babel">
                  class Item extends React.Component{
                    constructor(...args){
                      super(...args); 
                    }
                    render(){
                      return <li>{this.props.str}</li>;
                    }
                  }
                  class List extends React.Component{
                      constructor(...args){
                         super(...args);
                      }
                      render(){
                        let aItems = this.props.arr.map(a => <Item str={a}></Item >);
                        //for(let i=0;i<this.props.arr.length;i++){
                        // aItems.push(<Item str={this.props.arr[i]}></Item >)
                        //}
                        return <ul>
                          {aItems}
                        </ul>;
                      }
                  }
                  window.onload = function (){
                    let oDiv = document.getElementById('div1');
                    ReactDOM.render(
                      <List arr = { ['Flipped','good'] }></List >,
                      oDiv;
                    );
                  }
                </script>
        </head>
        <body>
          <div id="div1">
            
          </div>
        </body>

8.JSON

JSON 格式
 JavaScript Object Notation 的缩写,是一种用于数据交换的文本格式。JSON 是 JS对象的严格子集。
 JSON 的标准写法:
  只能用双引号
  所有的key都必须用双引号包起来
JSON 对象
 JSON 对象是 JavaScript 的原生对象,用来处理 JSON 格式数据,有两个静态方法:
  JSON.parse(string) :接受一个 JSON 字符串并将其转换成一个 JavaScript 对象。
  JSON.stringify(obj) :接受一个 JavaScript 对象并将其转换为一个 JSON 字符串。

let json={a:12,b:5};
//因为在作用与url当作参数传递的时候,如参数出现空格这样的特殊字段,
//后台只可以读取到空格前的内容,后面内容丢失,造成数据读取失败,
//但是如果用encodeURIComponent()包裹一下,那会将这些特殊字符进行转义,
//这样后台就可以成功读取了,所以encodeURIComponent()用于url作为参数传递的场景中使用
let str='https://www.baidu.com?data='+encodeURIComponent(JSON.stringify(json));
alert(str);

let json={a:12,b:5};
alert(JSON.stringify(json));  //json转字符串
let str = '{"a": 12, "b": 5, "c": "abc"}';
let json1 = JSON.parse(str);  //字符串转json
console.log(json1);

let a=12;
let b=5;
let json={a,b,c:55}; //名字和值一样,可以只写一个
console.log(json);

let json={
    a:12,
    /*show: function () {//旧写法
        alert(this.a);
    }*/
    show() {
        alert(this.a);
    }
};
json.show();

9.ES6的Promise

promise:为了解决异步编程中的回调地狱而产生


  • 异步:操作直接没啥关系,同时进行多个操作,回调嵌套多个就会产生回调地狱
  • 同步:同时只能做一件事

基本用法


Promise 对象是由关键字 new 及其构造函数来创建的。

首先,介绍一下如何创建一个 Promise;

// 方法1
let promise = new Promise ( (resolve, reject) => {
    if ( success ) {
        resolve(res) // pending ——> resolved 参数将传递给对应的回调方法
    } else {
        reject(err) // pending ——> rejectd
    }
} )

// 方法2
function promise () {
    return new Promise ( function (resolve, reject) {
        if ( success ) {
            resolve(res)
        } else {
            reject(err)
        }
    } )
}

该构造函数接收两个函数作为参数,分别是resolve和reject。
当异步操作执行成功后,会将异步操作结果作为参数传入resolve函数并执行;失败则会将异步操作的错误作为参数传入reject函数并执行;

然后通过then方法,分别指定resolved状态和rejected状态的回调函数。

  promise.then(function(value) {
      // 成功
  }, function(error) {
      // 失败
  });

.catch()的作用是捕获Promise的错误,与then()的rejected回调作用几乎一致。但是由于Promise的抛错具有冒泡性质,能够不断传递,这样就能够在下一个catch()中统一处理这些错误。同时catch()也能够捕获then()中抛出的错误,所以建议不要使用then()的rejected回调,而是统一使用catch()来处理错误

promise.then(
    (value) => { 
       //成功
     }
).catch(
    (err) => {
      //失败
    }
)

Promise方法

(1) Promise.all()

Promise的all方法提供了并行执行异步操作的能力,并且在所有异步操作执行完后才执行回调。

//如果传入的参数中存在不是Promise实例,则会先调用Promise.resolve,
//将其转为Promise实例,再进一步处理。
var a1 = Promise.resolve('kk');
var a2 = 'is';
var a3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'good');
}); 

Promise.all([a1, a2, a3]).then(values => { 
  console.log(values); 
});

//  ["kk", "is", "good"] 

(2) Promise.race()

Promise.race 的使用
race有赛跑之译,因此返回的新实例状态,是跟随参数中最先改变状态的那个实例;如果不是Promise实例,依旧先用Promise.resolve方法,转化后再进一步处理。
如果传的迭代为空,则返回的 Promise 永远等待

var promise1 = new Promise(function(resolve, reject) {
    setTimeout(resolve, 100, '第一个请求');
});

var promise2 = new Promise(function(resolve, reject) {
    setTimeout(reject, 200, '第二个请求');
});

Promise.race([promise1, promise2]).then(function(value) {
    console.log(value);
}, function(err) {
    console.log(err);
});
// 第一个请求

(3)Promise.resolve() / Promise.reject()
用来包装一个现有对象,将其转变为Promise对象,但Promise.resolve()会根据参数情况返回不同的Promise:

参数是Promise:原样返回
参数带有then方法:转换为Promise后立即执行then方法
参数不带then方法、不是对象或没有参数:返回resolved状态的Promise

Promise.reject()会直接返回rejected状态的Promise

10.ES6的generator - 生成器

普通函数--一路到底
generator函数--中间能停

function *show(){
  alert('a');
  yield;//放弃执行的权利,先暂时不往下走
  alert('b');
}
let genObj = show();
genObj.next(); //没有next不会执行函数下一步
genObj.next();

yield:可以传参和返回

//yield传参
function *show(){
  alert('a');
  let a = yield;
  alert('b');
  alert(a); //5
}
let genObj = show();
genObj.next(12);  //没法给yield传参,只执行到yield前面的代码
genObj.next(5);
//yield返回
function *show(){
  alert('a');
  yield 12;
  alert('b');
  return 44;//没有return的话res2的value值为undefined
}
let genObj = show(); 
let res1 = genObj.next();
console.log(res1);  //{ done: false, value: 12 }
let res2 = genObj.next();
console.log(res2); //{ done: true, value: 44 } 

通俗化就是以下伪代码

function *炒菜(菜市场买回来的){
  洗菜 -> 洗好的菜;
  let 干净的菜 = yield 洗好的菜;
  干净的菜 ->切->丝
  let 切好的菜 = yield 丝;
  切好的菜->炒->熟的菜
  return 熟的菜;
}

ES7 & ES8

1.数组 includes

数组是否包含某个东西

includes()作用,是查找一个值在不在数组里,若是存在则返回true,不存在返回false.

2.数组 keys/values/entries

数组 json
for...in 下标(key) 下标(key)
for...of 值(value) 不能用在json

key => 所有的key拿出来                        0,1,2,3

let arr = [12,5,7,99];
for(let key of arr.keys()){
    console.log(key) //0 1 2 3
}

values => 所有的values拿出来               12,5,7,99

let arr = [12,5,7,99];
for(let value of arr.values()){
    console.log(value) //12,5,7,99
}

entries => 所有的key-value对拿出来      {key:0, value: 12}, {key:1, value: 5}...

let arr = [12,5,7,99];
for(let entry of arr.entries()){
    console.log(entry)
}
//{0:0,1: 12}  {0:1, 1: 5}  {0:2,1:7}  {0:3,1:99}

3.幂

console.log(2**2) //4

4.padStart/padEnd

console.log('('+'abc'.padStart(10)+')'); //(       abc)
console.log('('+'abc'.padStart(10,'0')+')'); //(0000000abc)
console.log('('+'abc'.padEnd(10)+')'); //(abc       )

5.async await

async: 异步的意思。看代码

async function testAsync() {
    return "hello async";
}
console.log( testAsync() )  //输出结果是 Promise {<pending>}并不是"hello async"

async 的作用是申明一个异步函数,函数的返回值是promise 对象
即 async 函数返回的是一个 Promise 对象
await
await 是 async+wait 的结合 即异步等待,async和await 二者必须是结合着使用
await 是个运算符,用于组成表达式,await 表达式的运算结果取决于它等的东西。

function getSomething() {
    return "something";
}
async function testAsync() {
    return Promise.resolve("hello async");
}

async function test() {
    const a = await getSomething() // await 后面也可以不是promise对象
    const b = await testAsync()
    console.log(a, b);  // 输出结果是 “something hello async”
}

test() 

注意:
如果它等到的不是一个 Promise 对象,那 await 表达式的运算结果就是它等到的东西。
如果它等到的是一个 Promise 对象,await 就忙起来了,它会阻塞后面的代码,等着 Promise 对象 resolve,然后得到 resolve 的值,作为 await 表达式的运算结果。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容