javaScript的常用ES6标准语法

  • 全称ECMAScript6.0,是JavaScript的下一个版本标准,增加了新的语法特性
  • 一个JavaScript的统一标准,解决不同浏览器解析javaScript的不一致问题

一.let声明变量的基本使用

  • let声明的变量有严格局部作用域

    • let声明的变量,在代码块中,则作用域在代码块中
    • var声明的变量,在代码块中,作用域没有限制
    • 应用实例
    // (1) let 声明的变量, 在代码块中,则作用域在代码块中
    // (2) var 声明的变量, 在代码块中,作用域没有限制
    {
    var name = "韩顺平教育";
    let job = "java 工程师";
    console.log("name=", name);
    console.log("job=", job);
    }
    //var声明的变量可以正常输出
    console.log("name=", name);
    console.log("job=", job);//会报错,job is not defined
    
  • Iet只能声明一次,var可以声明多次

  • 应用实例

    // 1. var 可以声明多次
    // 2. let 只能声明一次
    var num1 = 100;
    var num1 = 200;
    console.log(num1);
    let num2 = 600;
    //Syntax => 语法
    let num2 = 900;
    //语法报错,let不能重复声明同一个变量名的变量
    //Uncaught SyntaxError: redeclaration of let num2
    
  • Iet不存在变量提升,var存在变量提升

  • 应用实例

    // 1. let 不存在变量提升
    // 2. var 存在变量提升
    console.log("x=", x);
    //会输出undefined,不会报错,因为在下面声明了x变量,只能在当前位置取不到值
    var x = "tom";
    console.log("z=", z);
    //会报错,let声明的变量有严格的循序要求
    //can't access lexical declaration 'z'
    let z = "mary";
    

二.const声明常量的基本使用

  • const用于声明一个常量,声明是必须赋值,且声明后不能修改

  • 应用实例

    const pi = 3.14;//声明常量必须赋值
    console.log(pi)
    

三.解构赋值

  • 解构赋值是对赋值运算符的扩展
  • 是一种针对数组或者对象进行模式匹配,然后对其中的变量进行赋值
  • 主要有两种形式:数组解构和对象解构

数组解构取赋值

  • 数组解构取值使用的是中括号
  • 应用实例
// 常规写法
console.log("常规写法");
var arr  = [100,200,300];
let x = arr[0],y = arr[1],z = arr[2];
console.log(x,y,z);//通过索引取出值
//解构写法
console.log("解构写法");
//数组解构取值使用的是中括号
let [a,b,c] = arr;
//将数组里的值取出一一对应赋给a,b,c变量
console.log(a,b,c);

对象解构取属性

  • 对象解构取值使用的是大括号
  • 取属性的值时,需要变量名与对象的属性名一致
  • 应用实例
let moster = {name:"牛魔王",age:100};
    //传统方式取属性的值
    let tname = moster.name;
    let tage = moster.age;
    console.log("name=",tname,"age=",tage);
    //解构的方式取属性的值
    //取值是变量名要与属性名保存一致
    let {name,age} = moster;
    console.log("name=",name,"age=",age);
    //方法的解构
    let f1 = function({name,age}){
        console.log("name=",name,"age=",age);
    }
    f1(moster);

四.模板字符串

  • 模板字符串使用反引号"`"将字符串包裹
  • 可作为普通字符串使用
  • 可用来定义多行字符串,即可以将换行字符串原生输出
  • 字符串插入变量和表达式,即可以插入JavaScript代码,使用${}
  • 字符串中调用函数
  • 应用实例
//模板字符串可以输出原格式的字符串
let str1 = `使用模板字符串
换行输出`;
console.log(str1);
//使用模板字符串插入JavaScript代码
let num1 = 10;
let num2 = 20;
let str2 = `num1 + num2 = ${num1 + num2}`;
console.log(str2);
//使用模板字符串调用函数
let f1 = function(name){
return "你的名字是"+name;
}
let str3 = `使用模板字符串调用函数,${f1("杨逸")}`;
console.log(str3);

五.ES6声明对象的新特性

声明对象的简写

  • 通过变量或常量直接在声明对象时,给对象的属性赋值
  • 应用实例
let name = "牛魔王";
let age = 100;
//传统的声明对象的方式
let object01 = {name:name,age:age};
console.log("传统的方式声明的对象",object01);
//ES6的新的对象声明对象方式
let object02  = {name,age};
//这里属性的值来着前面同名的变量或常量,如果前面没有声明这里变量或常量,就会报错
console.log("ES6的新方式声明的对象",object02);

ES6定义对象函数的新方式

  • 直接给对象创建一个函数,不用赋值给一个对象的属性
  • 应用实例
//传统方式定义对象方法
let object1 = {
    name:"牛魔王",
    age:100,
    //创建一个函数赋值给一个属性
    info:function () {
    	console.log("name=",this.name,"age=",this.age);
    }
}
object1.info();
//ES6的定义对象方法方式
let object02 = {
    name:"孙悟空",
    age:1000,
    //直接创建一个函数
    info(){
    	console.log("name=",this.name,"age=",this.age);
    }
}
object02.info();

对象操作符的扩展(对象的深拷贝)

  • 对象的浅拷贝:只是拷贝了一个对象的引用,对引用的修改也会影响到原对象
  • 对象的深拷贝:完完全全拷贝对象的数据,然后指向一个新对象变量,对这个新对象变量的修改,不会影响的原对象的属性
  • 应用实例
let car01 = {name:"小猫",age:100};
//对象的浅拷贝
let car02 = car01;
//对浅拷贝对象的修改会影响到原对象
car02.name = "大猫";
console.log("car01=",car01);
console.log("car02=",car02);
//ES6扩展的对象深拷贝
let monster01 = {name:"牛魔王",age:10};
let monster02 = {...monster01}; //深拷贝,使用大括号加上三个点
//对深拷贝的对象修改不会影响到原对象的属性
monster01.name = "孙悟空";
console.log("monster01=",monster01);
console.log("monster02=",monster02);

//利用深拷贝实现对象的合并
let object01 = {name:"对象一",age:100};
let object02 = {brand:"宝马",history:100};
let object03 = {...object01,...object02};
console.log("object01=",object01);
console.log("object02=",object02);
console.log("object03=",object03);
  • 运行结果截图

六.箭头函数 (lambda表达式)

  • 箭头函数提供更加简洁的函数书写方式。

  • 基本语法是:(参数列表)=>{函数体}

  • 箭头函数没有参数或有多个参数,要用小括号"()"括起来,箭头函数只有一个参数,可以省略小括号

  • 箭头函数函数体有多行语句,用大括号"{}"包裹起来,表示代码块

  • 函数体只有一行语句,并且需要返回结果时,可以省略大括号"{}",结果会自动返回

  • 箭头函数多用于匿名函数的定义

  • 应用实例一

//传统函数的定义和使用
let f1 = function(num){
    return num + 10;
}
console.log("传统函数的调用结果=",f1(10));
//箭头函数的定义和使用
let f2 = (num) =>{return num+10};
//只有一行语句且有返回时,可以省略大括号
let f3 = num => num + 10;
//以上三种写法都是等价的
console.log("箭头函数f2()的调用结果=",f2(10));
console.log("箭头函数f3()的调用结果=",f3(10));
//给函数传参时,也可以传入箭头函数
let f4 = function (f5){
    return f5(100);
};
console.log("调用f4()",f4(n=>n+10));
  • 应用实例二
//传统的函数
let f1 = function(begin,end){
    let result = 0;
    for (let i = begin; i <= end; i++) {
        result +=i;
    }
    return result;
}
console.log("传统的函数形式=",f1(1,10));
//箭头函数的形式
let f2 = (begin,end) =>{
    let result = 0;
    for (let i = begin; i <= end; i++) {
        result += i;
    }
    return result;
}
console.log("箭头的函数形式=",f2(1,10));
  • 箭头函数+对象解构
  • 应用实例
//传统的方式通过函数取出对象属性
let monster = {name:"哪吒",age:100,skill:["风火轮","三味真火"]};
let f1 = function (object){
	console.log("skill=",object.skill);
}
//箭头函数+对象解构的方式
let f2 = ({skill}) => console.log("skill=",skill);
f1(monster);
f2(monster);

七.Promise

  • 传统的Ajax异步调用在需要多个操作的时候,会导致多个回调函数嵌套,导致代码不够
    直观,就是常说的Callback Hell(回调地狱)
  • 为了解决上述的问题,Promise对象应运而生,在EMCAScript2015当中已经成为标准
  • Promise是异步编程的一种解决方案,可以解决传统Ajax回调函数嵌套问题
  • 问题提出
  • 嵌套多个ajax请求时,会产生可读性差,维护性低的问题
$.ajax({
    url:"data/monster.json",
    success(data,status,xhr){
        console.log("取回的数据",data);
        console.log("再次请求数据");
        $.ajax({
            url:`data/monster_detail_${data.id}.json`,
            success(data,status,xhr){
            console.log(`第二次请求的数据`,data)
        }
    	})
    },
    error(err){
   		console.log("请求数据失败",err)
    }
});
  • Promise对象的基本使用,解决ajax嵌套的问题
//先创建一个promise对象,传入一个箭头函数作为参数,箭头函数有两个参数resolve和reject
//在箭头函数中发起ajax请求
//在ajax请求成功后,如需要继续发起ajax请求,就调同resolve函数箭头函数,resolve()函数在promise对象的then()函数处执行
//在promise对象的then()函数中在创建一个promise对象并返回(返回的作用是为了能使用到新创建的promise对象的then()函数和catch()函数),就可以嵌套再发出一次ajax请求
// 请求失败,则调用reject()箭头函数,reject()函数在promise对象的catch()函数处执行
let p = new Promise((resolve,reject) =>{
    $.ajax({
        url:"data/monster.json",
        success(data){
            console.log("第一次ajax请求成功",data)
            //使用第一次ajax请求的结果,继续发起ajax请求
            resolve(data);
        },
        error(err){
            console.log("第一次ajax请求失败")
            //失败可以调用reject()函数处理
            //先进行一些特有的处理
            //最后统一的处理交给reject()函数处理
            reject(err);
        }
        })
	});

//调用promise对象的then()函数发起第二次ajax请求
//then函数的参数就是以上一次ajax请求返回的数据作为参数的箭头函数,等同于resolve函数在这里调用
p.then((data) =>{
    //发起ajax请求
    //再创建一个promise对象,并返回
    new Promise((resolve,reject) => {
        $.ajax({
            url:`data/monster_detail_${data.id}.json`,
            success(data) {
                console.log("第二次ajax请求的数据",data)
                //再次发起ajax请求
                resolve(data);
            },
            error(err) {
                console.log("第二次ajax请求失败")
                //调用reject()函数处理
                reject(err);
            }
        })
    }).then((data) => {
        //继续调用返回的promise对象的then()函数发起ajax请求
        //在创建一个promise对象
        return new Promise((resolve,reject) => {
                $.ajax({
                    url:`data/monster_${data.gfid}.json`,
                    success(data,status,xhr){
                        console.log("第三次ajax请求的数据",data)
                        //如有需要还可以继续发起ajax请求
                    },
                    error(){
                        console.log("第三次ajax请求失败");
                        reject(err)
                    }
                });
            });
        }).catch((err) => {
        	console.log("ajax请求失败的处理函数")
        });
})
  • 简化Promise对象嵌套ajax请求,代码重排
//将重复发出ajax请求的逻辑抽象出来,封装成一个函数
        function get(url,data){
            //返回一个promise对象
            return new Promise((resolve,reject) => {
                //发出ajax请求
                $.ajax({
                    url:url,
                    data:data,
                    success(data,status,xhr){
                        //请求成功调用resolve()函数
                        resolve(data);
                    },
                    error(err){
                        //请求失败调用reject()函数
                        reject(err);
                    }
                })
            });
        };

        //代码重排后嵌套ajax请求
        //使用抽象出来的函数发出ajax请求
        get("data/monster.json").then((data) =>{
            //调用promise对象的then()函数
            console.log("第一次请求的数据",data);
            //继续发出ajax请求
            return get(`data/monster_detail_${data.id}.json`);
        }).then(data => {
            console.log("第二次请求的数据",data);
            //调用第一次返回的promise对象的then()函数
            return get(`data/monster_${data.gfid}.json`);
        }).then(data => {
            console.log("第三次请求的数据",data);
        }).catch((err) => {
            //统一处理请求失败的函数
            console.log("统一处理请求失败的函数",err);
        });

8.模块化编程

es5中模块化编程的使用

  • 有一个function.js文件,希望在use.js文件中使用到function.js文件的代码
  • 先在function.js文件中使用module.exports = {}导出数据
  • use.js文件中使用require("url")导入数据
  • function.js文件
const sum = function (a,b){
    return a + b;
}

let name = "杨逸";
let monster = {
    name:"牛魔王",
    age:10
}
const PI = 3.14;
//导出模块,与对象形式类似
module.exports = {
    sum:sum,
    monster:moster,
    myname:name,
    pi:PI
}
//导入模块简写,当导出的数据与属性名相同时可以使用简写
exports = {
    sum,
    monster,
    name,
    PI
}
  • use.js文件
//为了使用function.js中代码,导入function.js
//相当于将function.js导出的数据封装到一个对象中,如何赋值给m
let m = require("./function.js");
//也可以使用对象解构的方式导入部分数据
let {PI} = require("./function.js");
//通过访问对象属性的方法使用导入的数据
console.log(m.sum(1,2));
console.log(m.monster);
console.log(PI)

es6中的模块化编程

  • ES6有三种导出数据的方式
    1. export{名称/对象/函数/变量/常量},与在es5中的导出简写类似
    2. export let xx = xxx,在定义变量时就导出
    3. export default{},默认导出
  • ES6有两张导入数据的方式
    1. import {} from "xx.js",从javascript文件中导入指定数据
    2. import名称form"xx.js",针对默认导出方式的导入数据方式,将默认导出的数据全部导入
  • 使用export{名称/对象/函数/变量/常量}导出数据
//定义数据
const sum = function (a,b){
    return a + b;
}

let name = "杨逸";
let monster = {
    name:"牛魔王",
    age:10
}
const PI = 3.14;
//导出数据
exports = {
    sum,
    name,
    monster,
    PI
}
  • 使用import {} from "xx.js"导入数据
//导入数据
import {sum,name,PI} from "./common01.js"
//使用导入的数据
console.log(name);
console.log(sum(1,3));
  • 使用export let xx = xxx,在定义变量时就导出数据
//在声明变量时,就导出数据
export let name = "杨逸";
  • 导入数据
//导入数据
import {name} from "./common02.js";
//使用导入的数据
console.log(name);
  • 使用export default{},默认导出数据
//定义数据
const sum = function (a,b){
    return a + b;
}

let name = "杨逸";
let monster = {
    name:"牛魔王",
    age:10
}
const PI = 3.14;
//默认导出可以看作导出了一个对象,与es5中的导出方式类似
export default {
    sum,
    PI,
    name,
    add(a,b){
        return a + b
    }
}
  • 使用import名称form"xx.js",导入默认导出的数据
//导入默认导出的数据
import m from "./common03.js";
//通过访问对象属性的方式使用导入的数据
console.log(m.name);

注意事项和使用细节

  1. ES6的模块化无法在Node.js中执行,需要用Babel转码ES5后再执行
  2. export不仅可以导出对象,一切变量都可以导出。比如:基本类型变量、函数、数组、对象
  3. 没有导出的不能使用
  4. ES6有导出方式较多,不同的导出方式对导入方式也有一定影响