- 概念:ES6全称ECMAScript6,是ES5的升级版本,在原有ES5基础之上增加一些新的语法规范。
- 作用:目前所有流行的前端架构都是基于ES6语法进行的项目构建,因此要想学习好流行框架,就必须提前掌握好常用的ES6语法。
ES6常用语法结构如下:
块级作用域变量
- 在ES5中定义变量用var关键字,但是var关键字定义的变量不存在块级范围,即该变量作用范围属于全局。
{
var name = "张三"; //name变量被定义在一个块级作用域中
}
console.log(name); //使用块级作用域中的变量,该变量不存在访问权限问题,输出结果为张三
- 在ES6中使用let定义变量,该变量被称为块级作用域变量,只能在定义的块级作用域或者其子级作用域中访问。
{
let name1 = "李四";
{
console.log('+++++++++++++++++++++');
console.log(name1);
console.log("--------------------");
}
}
console.log(name1);
- 避免出现变量数据污染:var定义的变量,在即使其中延迟输出,计时器属于异步执行的任务,在执行时循环已经结束,因为var定义的变量属于非块级作用域变量,因此每一次循环,变量并不会被及时销毁,故延迟执行输出结果为循环结束时变量i的值
for (var i = 0; i < 3; i++) {
var timer = setTimeout(function () {
console.log(i);
}, i * 1000);
}
- let定义的变量属于块级作用域变量,变量中的值只能应用当前块级范围,当块级范围运行结束时,变量中的数据会被清空回收,因此不会出现变量数据被污染
for (let i = 0; i < 3; i++) {
let timer = setTimeout(function () {
console.log(i);
}, i * 1000);
}
常量
const name1 = "张三";
const name1 = "张三";
//console.log(name1); //正确
name1 = "李四"; //报错
- 常量只能在定义时进行初始数据的赋值,之后不允许再一次赋值。
const name1 = "张三";
name1 = "李四"; //不允许再一次赋值
- 如果常量中存储的数据是一种复合结构,此时该复合结构内部允许数据修改。比如常量中存储的是对象或者数组,此时允许更改。
const obj = {
name: "张三",
age: 20,
sex: "男"
};
obj.name = "李四";
console.log(obj);
解构赋值
let num1 = 10,
num2 = 20;
[num1, num2] = [num2, num1]; //左右两侧都是数组结构,结构完全相同,此时右侧对应位置的
元素赋值给左侧对应位置的变量
console.log(num1, num2); //实现两个变量中数据的互换,输出结果为20,10
数组解构
- 必须保证左右两侧都是数组
// 快速定义多个变量
let [num1, num2, num3] = [10, 20, 30];
console.log(num1, num2, num3);//10,20,30
- 注意:解构赋值是按照数据一一对应的关系进行解构的
// 快速定义多个变量
let [num1, num2, num3] = [
[10, 20, 30], 20, 30
];
console.log(num1, num2, num3);//num1是一维数组,num2, num3都是数字,
对象解析
var {name, sex, age} = {
name: "张三",
age: 20,
sex: "男"
};
console.log(name, age, sex); //左右两侧必须是对象,并且左侧变量的名字必须要和右侧对象的key保持一致
- 对象的解构赋值可以帮助开发人员快速提取想要的指定数据
var {id} = {
name: "张三",
age: 20,
sex: "男",
birth:"2000-07-11",
id:"13229132901392091"
};
console.log(id);
- 对象解构赋值的变量重命名
var {
name: name1,
age: age1,
sex: sex1
} = {
name: "张三",
age: 20,
sex: "男",
birth: "2000-07-11",
id: "13229132901392091"
};
console.log(name1, age1, sex1); //变量重命名需要保证左侧key对应的value是一个重命名之后的变量
析构赋值(…param)
- 可以实现复合数据的快速融
let obj = {
name: "张三",
age: 20,
sex: '男'
};
obj = {
...obj, //析构赋值
name: "李四"
};
console.log(obj);
- …param:ES6的析构运算符,作用是将变量param最外层的数据结构去除,之后将结构内部的数据按照顺序进行排布,该过程被称为数据的析构过程。
- 作用:快速实现某一个复合结构中的数据和其他复合结构数据的融合。
ES6模块
- 定义若干个功能,之后导出(export)对应的功能
function getRandom(min,max){
return Math.floor(Math.random()*(max-min+1)+min);
}
//导出
export {getRandom};
function getColor(){
var red=getRandom(0,255);
var green=getRandom(0,255);
var blue=getRandom(0,255);
return `rgb(${red},${green},${blue})`;
}
//导出
export {getColor};
- 在需要使用的位置,导入对应的模块(import)
import {getRandom,getColor} from "../module";
导出:export,export default
function getRandom(min,max){
return Math.floor(Math.random()*(max-min+1)+min);
}
//导出
export {getRandom};
function getColor(){
var red=getRandom(0,255);
var green=getRandom(0,255);
var blue=getRandom(0,255);
return `rgb(${red},${green},${blue})`;
}
//导出
export {getColor};
// 产生[min, max]范围的随机整数的函数
function getRandom(min, max){
return Math.floor(Math.random()*(max-min+1)+min);
}
// 定义函数生成随机颜色
function getRandomColor(){
var red = getRandom(0,255);
var green = getRandom(0,255);
var blue = getRandom(0,255);
return `rgb(${red}, ${green}, ${blue})`;
}
export default {getRandomColor, getRandom};
两者区别:
- export可以在开发时随时随地导出需要导出的模块内容,因此该方法导出模块时比较灵活。但是export default该方法导出只能在所有代码的最后边导出一次,因此该方法只能出现在所有模块代码的最下边。
- export导出模块时,当代码过于庞大,因为导出过程比较灵活,可以做到随时随地导出,因此在进行导出模块代码查询时难度比较大。但是export default因为只能用一次,并且只能出现在代码的最后边,因此在进行导出模块查询时可以非常清楚的知道都导出了哪些模块。
- export导出模块时,外界如果需要使用,可以通过解构赋值的方式,只获取有用的模块,因此对于程序整体运行效率比价高。但是export default是一次性将所有模块导出,外界不管是否需要对应的模块功能,该功能都会被导出,因此对整个程序的运行效率会产升不利影响。
import {getRandom,getColor} from "../module";
import obj from "./module";
- 综上:在开发中如果某一个文件中模块过于庞大(太多),此时导出选择export,如果模块比较少,为了方便代码的可读性,用export default
导入
- ES6中完成模块的导入通过关键字import 模块名 from “路径”
- 对于模块使用export导出,此时导入应该基于对象的解构赋值方式进行导入
//export导出时对应的导入方式
import {getRandom,getColor} from "../module";
- 对于模块使用export default导出的,此时导入直接导入一个对象,通过变量接收该对象即可使用对象中对应的属性数据
//export default导出时对应的导入方式
import obj from "./module";
obj.getRandom(0,255);
箭头函数
let fun=(num1,num2)=>{
return num1+num2;
}
console.log(fun(10,20));//30
- 当箭头函数函数题代码只有一句,而且最终该句代码对应结果需要返回时可以进行简写
//简写,将num1+num2的和返回给外界,该写法只适用于函数体中只存在一句代码
let fun=(num1,num2)=>num1+num2;
console.log(fun(10,20));
- 箭头函数定义时,函数内部的this关键字是由函数定义时所处的上下文环境决定的,不会随着调用者的改变而发生改变.
- 定义的对象obj
var obj1 = {
name: "对象1",
sayHello: function () {
//箭头函数作为sayHello闭包函数返回给外界
return () => {
console.log(this.name);
}
}
}
- 定义另一个对象obj2
var obj2 = {
name: '对象2',
say: obj1.sayHello() //将obj1对象调用sayHello返回的箭头函数作为obj2的say功能绑定给obj2
};
- obj2调用say功能,此时输出的name属性为obj1对象的name属性,即此时this的指向指向obj1对象
obj2.say();
面向对象
ES6加入了完成类和对象的概念,弥补了ES5中对面向对象的鸡肋定义。
类的定义
class Person {
// 构造函数,等价于ES5中的构造对象
constructor(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
//功能(函数)
sayHello() {
console.log(this.name + "正在打招呼");
}
}
- constructor系统内置函数,用来完成当前对象的构造,该函数中一般用来为对象添加属性
- ES6中类在定义时,所有的函数去除function关键字
对象的定义
//对象的构建
const per = new Person("张三", 20, "男");
console.log(per.name);
per.sayHello();
继承
- 子类在继承父类的情况下,如果需要添加额外的属性必须要实现constructor方法。如果直接父类的属性,constructor可以选择性实现。
class Student extends Person{
study(){
console.log(this.name+"正在学习");
}
}
const stu=new Student("李四",21,"男");//李四正在学习
- 子类需要添加额外属性
class Student extends Person{
constructor(name,age,sex,s_id,classroom,major){
//应用于子类的constructor函数中,代表使用当前子类对象调用父类的constructor进行构造.
super(name,age,sex);
this.s_id=s_id;
this.classroom=classroom;
this.major=major
}
study(){
console.log(this.name+"正在学习");
}
introduce(){
console.log(`我叫${this.name},今年${this.age}岁,在${this.s_id}班,专业为${this.classroom}`);
}
}
const stu=new Student("李四",21,"男",11000,"研发","HTML5全栈");
stu.study();
stu.introduce();