该系列文章是博主学习前端入门课程的笔记,同时也为了方便查阅,有任何问题都欢迎在评论区提出。本文主要介绍ES6新特性,包括let和const命令、模板字符串、函数相关的新特性、解构赋值。默认读者具有JavaScript基础
思维导图
第一章 介绍
1.1 为什么要学ES6
ES5语言的先天性不足,比如变量提升、内置对象的方法不灵活、模块化实现不完善等等
为后面Vue,尤其是React框架的学习做准备
目前大部分公司的项目都在使用ES6
1.2 简介
ECMAScript 6.0(以下简称ES6)是JavaScript语言的下一代标准,已经在2015年6月正式发布了。它的目标,是使得JavaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语言。
ES6既是一个历史名词,也是一个泛指,含义是5.1版以后的JavaScript的下一代标准,涵盖了ES2015、ES2016、ES2017等等,而ES2015则是正式名称,特指该年发布的正式版本的语言标准。
1.3 ES6新特性
1.4 浏览器支持
各大浏览器的最新版本,对ES6的支持可以查看https://kangax.github.io/compat-table/es6/。随着时间的推移,支持度已经越来越高,超过90%的ES6语法特性都实现了。
1.5 强大的babel
被称为下一代的JavaScript编辑器,可以将ES6代码转换成ES5代码,从而获得浏览器支持
这里只需要知道babel的作用,不需要过多了解
1.6 参考文献
阮一峰的技术文档:https://es6.ruanyifeng.com/ 强烈推荐!!!
第二章 let和const命令
let和const都用于声明变量,在讲解之前,首先介绍ES5中var声明变量的不足之处
2.1 var的不足之处
存在变量提升
console.log(a);
var a = 2;
//等价于
var a;
console.log(a);
a = 2;
可以重复声明,会覆盖先前声明的值
var a = 1;
a = 2;
console.log(a);
2.2 let的性质
没有变量提升
console.log(b);
let b = 2;
只在声明的块内有效
//console.log(b);
{
let b = 2;
}
console.log(b);
不能重复声明
let a = 1;
let a = 2;
console.log(a);
2.3 const的性质
具有let的三个性质,但是只能声明常量
一旦被声明,不能被修改
const max = 30;
max = 40;
console.log(max);
const声明的对象内部的属性可以被修改
const person = {
name: '小马哥',
}
person.name = 'alax';
console.log(person);
2.4 let和const的作用
防止内层变量覆盖外层变量
var arr = [];
for (var i = 0; i < 10; i++) {
arr[i] = function () {
return i;
}
}
console.log(arr[5]()); //输出为10
因为var存在变量提升,所以最后for循环执行到i=10提升到全局导致所有数组中返回的i都变成10
const arr = [];
for (let i = 0; i < 10; i++) {
arr[i] = function () {
return i;
}
}
console.log(arr[5]()); //输出为5
let声明的变量只在块作用域生效,而每次for循环都会生成一个新的块作用域,相当于每一次循环的i都是一个新的变量。所以输出的是5
不会污染全局变量
let RegExp = 10;
console.log(RegExp);
console.log(window.RegExp);
第三章 模板字符串
利用js脚本动态给向HTML中追加内容时,es6可以使用模板字符串的写法,而不用像es5进行拼接(非常繁琐)。
语法格式
<div class="box">
</div>
<script>
const oBox = document.querySelector('.box');
let id = 1, name = '小马哥';
// es5写法
oBox.innerHTML = '<ul><li><p id=' + id + '>' + name + '</p></li></ul>';
// es6模板字符串,注意使用的是反引号``
let htmlStr = `<ul>
<li>
<p id=${id}>${name}</p>
</li>
</ul>`
oBox.innerHTML = htmlStr
</script>
效果图
第四章 函数相关
4.1 带参数默认值的函数
es5的写法
function add(a, b) {
a = a || 20;
b = b || 10;
return a + b;
}
console.log(add());
es6的写法
function add(a = 20, b = 10) {
return a + b;
}
console.log(add());
默认的表达式也可以是一个函数
function add(a, b = getVal(5)) {
return a + b;
}
function getVal(val) {
return val + 5;
}
console.log(add(5));
4.2 剩余参数
由三个点...和一个紧跟着的具名参数指定。形式为...变量名,用于获取函数的多余参数
es5的写法
function pick(obj) {
let result = Object.create(null);
for (let i = 1; i < arguments.length; i++) {
result[arguments[i]] = obj[arguments[i]]
}
return result;
}
let book = {
title: 'es6的教程',
author: '小马哥',
year: '2019',
}
let bookData = pick(book, 'title', 'year', 'author')
console.log(bookData);
es6的写法
function pick(obj, ...keys) {
let result = Object.create(null);
console.log(keys);
for (let i = 0; i < keys.length; i++) {
result[keys[i]] = obj[keys[i]];
}
return result;
}
let book = {
title: 'es6的教程',
author: '小马哥',
year: '2019',
}
let bookData = pick(book, 'title', 'year', 'author');
console.log(bookData);
讲解
pick(book, 'title', 'year', 'author')传入了四个参数,book传给obj,多余的'title', 'year', 'author'以数组的形式(剩余参数可以使用数组的所有属性)传到...key,注意剩余参数后面不能再有任何参数(即只能是最后一个参数)
好处
arguments对象不是数组,而是一个类似数组的对象。所以为了使用数组的方法,必须使用Array.from先将其转为数组。rest 参数就不存在这个问题,它就是一个真正的数组,数组特有的方法都可以使用。
4.3 扩展运算符
形式与剩余参数一致,但是功能不同。扩展运算符是将一个数组分割,并将各个项作为参数传给函数
语法格式
const maxNum = Math.max(20, 30);
console.log(maxNum);
const arr = [10, 20, 50, 100, 60, 80];
// es5
console.log(Math.max.apply(null, arr));
// es6
console.log(Math.max(...arr));
4.4 箭头函数
使用=>定义匿名函数
语法格式
// es5
let add = function (a, b) {
return a + b;
}
//es6
let add = (a, b) => {
return a + b;
}
// 一个参数
let add = val => (val + 5);
console.log(add(15));
// 没有参数
let fn = () => ('hello world');
console.log(fn());
//如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用return语句返回
var sum = (num1, num2) => { return num1 + num2; }
//由于大括号被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外面加上括号,否则会报错。
let getObj = id => ({ id: id, name: '小马哥' });
闭包函数
// es5
let fn = (function () {
return function () {
console.log('hello es5');
}
})();
fn();
// es6
let fn = (() => {
return () => {
console.log('hello es6');
}
})();
fn();
this指向
箭头函数没有this指向,内部this值只能通过查找作用域链。一旦使用箭头函数,当前就不存在作用域
语法格式
// 1.es5中this指向:取决于调用该函数的上下文对象
let PageHandle = {
id: 123,
init: function () {
document.addEventListener('click', function (event) {
this.doSomethings(event.type);
}.bind(this), false) //把this指向改变
},
doSomethings: function (type) {
console.log(`事件类型:${type},当前id:${this.id}`);
}
}
PageHandle.init();
// es6
let PageHandle = {
id: 123,
init: function () {
//由于箭头函数没有this指向,所以使用addEventListener()不会将this指向转到全局
document.addEventListener('click', (event) => (this.doSomethings(event.type)))
},
doSomethings: function (type) {
console.log(`事件类型:${type},当前id:${this.id}`);
}
}
PageHandle.init();
注意事项
使用箭头函数,函数内部没有arguments
let getVal = (a, b) => {
console.log(arguments);
return a + b;
}
console.log(getVal(1, 3));
箭头函数不能用new关键字来实例化对象
let Person = () => { };
let Fn = function () {
}
let p = new Person();
let fn = new Fn();
第五章 解构赋值
按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构
给对象结构
let node = {
type: 'iden',
name: 'foo',
}
// es5
let tyle = node.type;
let name = node.name;
console.log(type, name);
// es6
let { type, name } = node; //完全结构,注意{}内的变量名必须和对象中的属性名一致
console.log(type, name);
let{type} = node; //不完全结构
//默认值
let { a, b = 30 } = { a: 20 };
console.log(a, b);
对数组解构
let arr = [1, 2, 3];
let [a, b, c] = arr;
console.log(a, b, c);
嵌套
let [a, [b], c] = [1, [2], 3]
console.log(a, b, c);