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有三种导出数据的方式
export{名称/对象/函数/变量/常量}
,与在es5中的导出简写类似export let xx = xxx
,在定义变量时就导出export default{}
,默认导出
- ES6有两张导入数据的方式
import {} from "xx.js"
,从javascript文件中导入指定数据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);
注意事项和使用细节
- ES6的模块化无法在Node.js中执行,需要用Babel转码ES5后再执行
- export不仅可以导出对象,一切变量都可以导出。比如:基本类型变量、函数、数组、对象
- 没有导出的不能使用
- ES6有导出方式较多,不同的导出方式对导入方式也有一定影响