前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ES6-语法基础

ES6-语法基础

作者头像
用户10175992
发布2022-11-15 13:24:19
4610
发布2022-11-15 13:24:19
举报
文章被收录于专栏:辰远

1 ES6 的兼容性和新特性

1.1 兼容性

IE10+、Chrome、FireFox、移动端等新一代浏览器。

1.2 对旧版本的浏览器支持方式

(1)方式一:在线转换(使用 babel 转译库) 

代码语言:javascript
复制
<script src="browser.js" ></script>
<script type="text/babel"> ... </script>

(2)方式二:提前编译

1.3 ES6 的新特性

(1)变量定义的改进;

(2)箭头函数;

(3)数组 和 字符串 的改进;

(4)面向对象;

(5)Promise;

(6)generator;

(8)模块化。

2 ES6 中的变量

2.1 var定义变量的问题

(1)可以重复声明;(2)无法限制修改(无常量);(3)没有块级作用域。

代码语言:javascript
复制
if(true){
    var a = 12;
}
alert(a);   //正常运行,依然可以使用

2.2 let :不能重复声明的块级变量

不能重复声明:

代码语言:javascript
复制
let a=10; let a=15; //a变量重复定义,SyntaxError
alert(a);

块级作用域:

代码语言:javascript
复制
if(true){
    let a = 12;
}
alert(a);   //超出作用域,ReferenceError

块级作用域的重要性:

代码语言:javascript
复制
window.onload = function(){
    var buttons = document.getElementsByTagName("button");
    for(var i=0; i<buttons.length; i++){                    //使用var,每个按钮点击都显示3;改用let,则正确显示了按钮格各自下标
        buttons[i].onclick = function(){
            alert(i);
        };
    }
};

2.3 const :不能重复声明的块级常量

3 函数

3.1 箭头函数(Lambda表达式)

箭头函数是把函数简写成一个表达式;如果只有一个参数,()可以省略;如果只有一个行,{ }可以省略,return 可以省略。

(参数1,...) => { 函数体; }

代码语言:javascript
复制
let arr = [5,3,4,7,6,2];
arr.sort( (n1,n2)=>n2-n1 );

3.2 默认参数

代码语言:javascript
复制
function show(a, b=5, c=10){
    alert([a,b,c]);
}
show(1,2)

4 展开运算符

语法:...数组变量

(1)参数的收集(不定参数)

代码语言:javascript
复制
function showOthers(a,b,...others){
  alert(others);
}
showOthers(1,2,3,4,5);  //显示3,4,5

(2)数组的展开

代码语言:javascript
复制
function showSeperate(a,b,c){
    alert(a); alert(b); alert(c);
}
showSeperate(...args);

(3)多个数组展开

代码语言:javascript
复制
let arr1 = [3,2,1]; let arr2 = [4,5,6];
let arr3 = [...arr1, ...arr2];

5 解构赋值

5.1 解构赋值要点:(1)左右两边结构相同;(2)右边必须是对象(数组)(3)声明和赋值不能分开。

5.2 具体使用

(1)数组的解构赋值

代码语言:javascript
复制
let arr=[1,2,3];
[x,y,z] = arr;          //x=arr[0]; y=arr[1]; z=arr[2];

(2)对象的解构赋值

代码语言:javascript
复制
let point = {x:3,y:-5};
let {x,y}=point;        //变量需要与对象属性同名才能赋值

(3)复合

代码语言:javascript
复制
let [obj,arr,num,str]=[{x:10,y:20},[1,2,3],101,'hi'];
console.log(obj,arr,num,str);
let [{x,y},[n1,n2,n3],num,str]=[{x:10,y:20},[1,2,3],101,'hi'];
console.log(x,y,n1,n2,n3,num,str)

6 数组的增强

(1)map         映射函数(1对1变换)

代码语言:javascript
复制
let arr=[95,72,55,100,45,33];
let result = arr.map(x=>x>=60?'Pass':'Fail');       //["Pass", "Pass", "Fail", "Pass", "Fail", "Fail"]

(2)reduce     汇总函数

代码语言:javascript
复制
let arr=[95,72,55,100,45,33];
let sum = arr.reduce((tmp, item, index)=>{
    console.log(tmp, item, index);
    return tmp+item;
});

值得注意的是当数组为空时,reduce可能会出错,需要额外加入一个初始值(可以是0也可以根据需要设定)。

代码语言:javascript
复制
let arr=[];
var result = arr.reduce((x,y)=>x+y);        //错误,TypeError,
var result = arr.reduce((x,y)=>x+y, 0);     //正确,返回初始值 0

 (3)filter          过滤

代码语言:javascript
复制
let arr=[95,72,55,100,45,33];
let result = arr.filter(x=>x>=60);

(4)forEach    迭代

代码语言:javascript
复制
arr.forEach(x=>console.log(x))

7 模板字符串

ES6中可以使用反引号(`)定义模板字符串。模板字符串可以在字符串中换行;也可以把变量放入模板字符串的占位符中。

代码语言:javascript
复制
let title = "Hello ES6";
let tmpl = `<div>
    <h1>${title}</h1>
</div>`;

8 面向对象

8.1 传统的对象化

(1)对象的定义

代码语言:javascript
复制
function User(name,pass){
    this.name = name;
    this.pass = pass;
}
User.prototype.sayHi = function(){
    alert("Hi, I'm "+this.name);
}
var user = new User("zhang3","123");
user.sayHi();

(2)对象继承

代码语言:javascript
复制
function VipUser(name, pass, level){
    User.call(this, name, pass);
    this.level = level;
}
VipUser.prototype = new User();
VipUser.prototype.construtctor = VipUser;
VipUser.prototype.showLevel = function(){
    alert("My Level is: "+this.level);
}
var vip = new VipUser("li4","123",5);
vip.sayHi();
vip.showLevel();

8.2 ES6中的面向对象

(1)类的定义

使用 class 关键字定义类;新增 constructor 声明构造方法;可以在 class 中直接定义方法“方法名(参数列表) { ...方法体... }”

代码语言:javascript
复制
class User{
    constructor(name, pass){
        this.name = name;
        this.pass = pass;
    }
    sayHi(){
        alert("Hi, I'm "+this.name);
    }
}

(2)类的继承

代码语言:javascript
复制
class VipUser extends User{
    constructor(name, pass, level){
        super(name, pass);
        this.level = level;
    }
    showLevel(){
        alert("My Level is: "+this.level);
    }
}
var vip = new VipUser("li4","123",5);
vip.sayHi();
vip.showLevel();

9 JSON语法改进

9.1 ES5 的 JSON 对象

(1)把字符串解释为JSON对象

代码语言:javascript
复制
var line = '{"name":"zhang3","age":30}';
var obj = JSON.parse(line);

注意点:JSON字符串中的属性名必须使用引号声明:"属性名";JSON字符串中的字符串值只能使用双引号 "。

(2)把JSON对象序列化为字符串

代码语言:javascript
复制
JSON.stringify(obj)

9.2 JSON的简写

(1)JSON对象的属性名和属性值(变量)同名时,变量值可以省略。

代码语言:javascript
复制
var x=10;y=20;
var point = {x, y};   // {x: 10, y: 20}

(2)JSON对象的方法声明可以简写

代码语言:javascript
复制
var point = {
    x, y,
    display(){ console.log(x, y); }     //等同于:display:function(){console.log(x,y);}
};

10 Promise 对象与异步调用

在JavaScript的世界中,所有代码都是单线程执行的由于这个“缺陷”,JavaScript的所有需要等待的操作(网络操作),都必须“异步执行”。“异步编程”通过“回调函数”实现,一个在“同步编程”中一段连续的调用,在“异步”中很可能会陷入“回调地狱”(Callback Hell)。

10.1 传统的AJAX回调

(1)AJAX回调

代码语言:javascript
复制
function getUserInfo(){
        $.ajax({
            url:"data/user.json", 
            dataType:"json",
            success: function(user){ console.log(user); },
            error: function(err){ console.log(err); }
        });
    }
    getUserInfo();

(2)回调中的回调(Callback Hell)

代码语言:javascript
复制
function getProductsOfUser(){
        $.ajax({
            url:"data/user.json", 
            dataType:"json",
            success: function(user){
                $.ajax({
                    url:"data/"+user.username+".json",
                    dataType:"json",
                    success: function(products){
                        console.log(products);
                    },
                    error:function(err){ console.log(err); }
                });
            },
            error: function(err){ console.log(err); }
        });
    }
    getProductsOfUser();

10.2 使用 fetch 实现 Promise 异步调用。

实际中,支持 ES6 的浏览器,都可以使用 fetch 对象实现基于 Promise 的异步请求,无需使用 jQuery 实现异步调用。

上述示例可以使用 fetch 简单实现。

代码语言:javascript
复制
fetch("data/user.json")
    .then(resp=>resp.json())
    .then(user=>fetch("data/"+user.username+".json"))
    .then(resp=>resp.json())
    .then(products=>console.log(products))
    .catch(err=>console.log('请求失败'));

10.3 什么是 Promise 对象

Promise对象的出现,用链式调用的形式替代了嵌套回调,解决“回调地狱”问题。

(1) 一个简单的 Promise 示例

代码语言:javascript
复制
//创建异步执行方法 async(resolve, reject),提供resolve(成功)和reject(失败)两个函数作为参数
function test(resolve, reject) {
    var timeOut = Math.random() * 2;
    console.log('设置超时时间为: ' + timeOut + ' 秒.');
    setTimeout(function () {
        if (timeOut < 1) {
            console.log('调用 resolve()...');
            resolve('200 OK');
        }
        else {
            console.log('调用 reject()...');
            reject('超时 ' + timeOut + ' 秒.');
        }
    }, timeOut * 1000);
};
//调用Promise,并实现 resolve(then)和reject(cache)
new Promise(test).then(function(result){
    console.log("成功:"+result);
}).catch(function(reason){
    console.log("失败:"+reason);
});

Promise对象的结构如下图所示:

(2)Promise 封装异步处理

代码语言:javascript
复制
//获取用户信息
function getUser(){
    return new Promise(function(resolve,reject){
        $.ajax({
            url:"data/user.json", 
            dataType:"json",
            success: resolve,
            error: reject
        });
    })
}
getUser()
    .then(function(user){ console.log(user); })
    .catch(function(err){ console.log("加载失败",err); });

(3)Promise的串行调用

多个Promise对象可以使用 then方法实现串行化调用。

代码语言:javascript
复制
//乘法
function multiply(input) {
    return new Promise(function (resolve, reject) {
        console.log('计算 ' + input + ' x ' + input + '...');
        setTimeout(resolve, 500, input * input);
    });
}
//加法
function add(input) {
    return new Promise(function (resolve, reject) {
        console.log('计算 ' + input + ' + ' + input + '...');
        setTimeout(resolve, 500, input + input);
    });
}
//创建Promise,初始化Resolve
var p = new Promise(function (resolve, reject) {
    console.log('启动 new Promise...');
    resolve(123);
});
//串行调用多个Promise对象,前面的函数执行结果会传入到后面的函数
p.then(multiply)
 .then(add)
 .then(multiply)
 .then(add)
 .then(function (result) {
    console.log(': ' + result);
});

(4)使用 Promise 串行执行多次AJAX回调

上述的fetch方法,then回调中的参数是响应而不是json,为了使用更简便,我们可以利用Promise的特性加上jQuery,自己实现一个then回调是json的Promise异步请求函数fetchJOSN,并实现多此Promise的嵌套调用。

代码语言:javascript
复制
function fetchJSON(url){
  return new Promise((resolve, reject)=>{
    $.ajax({
      url:url,
      dataType:"json",
      success: resolve,
      error: reject
    })
  });
};
fetchJSON("data/user.json")
  .then(user => fetchJSON("data/"+user.username+"1.json"))
  .then(products=>console.log(products))
  .catch(err => console.log('请求失败', err));

11 Generator

11.1 generator的定义

generator(生成器)是ES6标准引入的新的数据类型。一个generator看上去像一个函数,但可以执行并返回多次。

语法:function* 生成器名( 参数... ){ ...函数体... }

代码语言:javascript
复制
function* show(){
    alert('x');
    yield;          //退让
    alert('y');
}
let gen = show();
gen.next();         //显示x
gen.next();         //显示y

11.2 yield

(1)使用 yield 传参

代码语言:javascript
复制
function* show(init){
    alert(init);
    let x = yield;
    alert(x); 
}
var gen = show(101);
gen.next();         //101
gen.next(202);      //202

(2)使用 yield 返回中间结果

代码语言:javascript
复制
function* show(){
    alert('x');
    yield 101;          //返回
    alert('y');
}

执行效果如下图所示:

11.3 generator+Promise

使用 generator 中的 yield 去调用一个 Promise 对象,就可以把异步调模仿成同步调用的形式来执行。

定义一个异步变同步的执行函数(syncRun.js):

代码语言:javascript
复制
/* 把异步当做同步执行的函数,详见《你不知道的JavaScript-中卷》 4.4.1 */
function syncRun(gen){
    var args = [].slice.call(arguments, 1), it;
    //初始化生成器
    it = gen.apply(this, args);
    return Promise.resolve()
        .then(function handleNext(value){
            //对下一个yield出的值运行
            var next = it.next(value);         
            return (function handleResult(next){
                //生成器执行完了吗?
                if(next.done){
                    return next.value;  //执行完返回值
                }else{                  //否则继续执行
                    return Promise.resolve(next.value)
                        .then(
                            handleNext, 
                            function handleErr(err){
                                return Promise.resolve(it.throw(err))
                                    .then(handleResult);
                            }
                        );
                }
            })(next);
        });
}

把异步Promise以同步的形式执行。

代码语言:javascript
复制
<script src="js/syncRun.js"></script>
<script>
    syncRun(function* (){
        let resp = yield fetch('data/user.json');
        let user = yield resp.json();
        resp = yield fetch('data/'+user.username+'.json');
        let products = yield resp.json();
        console.log(products);
    });

</script>

12 ES7 中的 async / await

ES7中添加了 async 与 await 关键字,可以进一步将Promise调用编写成类似同步的语法。

async函数是使用async关键字声明的函数。 async函数是AsyncFunction构造函数的实例, 并且其中允许使用await关键字。

async和await关键字让我们可以用一种更简洁的方式写出基于Promise的异步行为,而无需刻意地链式调用Promise。

例如有如下的Promise函数:

代码语言:javascript
复制
var flag=false;   //用于控制Promise,模拟“成功”和“失败”
    //创建Promise函数
    function promiseFunc(){
      return new Promise((resolve, reject)=>{
        setTimeout(() => {
          if(flag)
            resolve("success");
          else
            reject("fail");   
        }, 2000);
      });
    }

下面时Promise的一般调用方式,我们需要编写成链式调用:

代码语言:javascript
复制
 //链式调用Promise
    promiseFunc()
        .then(x=>console.log("链式调用Promise:",x))
        .catch(e=>console.log("链式处理异常:", e));

如果使用 async/await 方式调用,我们可以通过 async 方法返回值来获取 resovle(即then)回调中的参数,也可以通过 catch 来获得 reject(即catch)回调中得错误信息。

代码语言:javascript
复制
 //在使用async函数中使用await调用Promise
    async function asyncFunc(){
      try{
        var x = await promiseFunc();
        console.log("await调用Promise:", x);
      }catch(e){            //异常处理可选
        console.log("await处理异常:", e);
      }
    }
    asyncFunc();

async函数还可以被作为表达式来定义,例如上述调用可以简化为以下得自执行函数:

代码语言:javascript
复制
 //用自执行函数来直接await调用
    (async ()=>{
      try{
        var x = await promiseFunc();
        console.log("await调用Promise:", x);
      }catch(e){
        console.log("await处理异常:", e);
      }
    })()
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-12-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档