文章目录
1、ES6概述
(1) 什么是ES6
ES
:是ECMA
缩写,是 欧洲计算机制造商协会联盟 组织的缩写,这个组织结合国际标准化组织制定了大量的计算机行业的规范和标准,被所有的计算机制造商和计算机周边遵守!
网景公司为了推动前端编程语言的发展,将自己的JavaScript
脚本语言贡献给ECMA
组织用于制定前端编程语言标准,标准化组织推出了ECMAScript
语法标准
ECMAScript
:语言规范和语法标准JavaScript
:语言的一种实现- 注意:
ECMAScript
语法标准是基于JavaScipt
进行制定,所以行业内一般称呼ES
语法的时候说的都是JS
语法
(2) ES6版本问题
JavaScript
从推出到更名差不多1996年前后
- 1997年6月:
ECMAScript 1
语法规范出台 - 1998年6月:
ECMAScript 2
语法规范 - 1999年12月:
ECMAScript 3
语法规范 ECMAScript 4/5
版本,语法规范上和语法标准上进行了高度升级,导致大量语法更新和编程理念的转换,所以再经过多次商讨之后,该版本废弃- 2009年12月:
ECMAScript 5.1
语法规范,目前最全的前端语法规范版本 - 2015年6月:
ECMAScript 6
语法规范发布,也就是后来经常说的ES6
- 从这一年开始,版本从普通的数字声明,更改为使用年份声明
ES6
也称为ES2015
- 2016年6月:
ECMAScript 2016
语法规范- 从这一年开始,几乎每年都会出台新的规范,对上个版本的规范进行补充
注意事项:
- 尽管每年都有
ES
新规范推出,但是ES6/ES2015
规范是承前启后的最全的/增量最多的一版规范,所以后来前端语法标准中,我们都以ES6
规范为主进行学习
思考:什么是ES6
?
2、变量声明扩展
(1) 原生JS
原生JavaScript
中声明变量:
// 直接使用变量(不推荐:导致代码的可读性严重下降,同时很容易造成变量全局污染)
name = "damu"
// 标准语法(声明变量- 全局变量、局部变量)
// 函数外部声明的变量,全局变量
// 函数内部声明的变量,局部变量
// 存在变量预解析
var age = 22;
操作案例:
// 1、声明和使用
var name = "文帝"
console.log(name)
// 2、全局和局部
function fn() {
var age = 22
console.log(age) // 22
}
fn()
console.log(age) // 错误 age is not defined
// 3、代码结构(花括号内部)
if(true) {
var gender = "男"
}
console.log(gender) // 男
// 4、变量预解析
console.log(job) // 不会报错,undefined
var job = "开发工程师"
// 5、全局变量在循环中
for (var i = 0; i < 10; i++) {
console.log(i) // 0 1 2 3 4 5 6 7 8 9
}
for (var i = 0; i < 10; i++) {
setTimeout(function () {
console.log(i) // 10 10 10 10 10 10 10 10 10 10
})
}
(2) ES6
鉴于原生JS
中var
声明变量的方式,对变量的行为不可控,导致代码的运行结果难以预测(尤其是对于新手开发人员),ES6
规范中扩展了两个用来声明操作数据的关键字
let
:声明变量,存在块级作用域(大括号范围也可以是一个作用域)、没有变量预解析、不能重复声明等等const
:声明常量,常量一旦声明不能改动
① let
作用:声明变量
// 二、ES6 let关键字
let name = "文帝"
console.log(name, "name")
// 1、不能重复声明
// let name = "Wendy"
//Uncaught SyntaxError: Identifier 'name' has already been declared
// 未处理的 语法 错误: 标识符 name 已经被声明过了
// 2、预解析:不支持预解析功能
// console.log(age)
// Uncaught ReferenceError: Cannot access 'age' before initialization
// 为处理的 引用 错误: 不能在age变量声明之前访问
let age = 22
// 3、全局变量.局部变量
function fn() {
let gender = "男"
console.log("函数内:", gender)
}
fn()
// console.log("函数外:", gender) // gender没有定义
// 4、块级作用域
if (true) {
let job = "需求分析工程师"
// 声明的job只能在当前花括号内部使用:块级作用域
}
// console.log(job, "job") // job没有定义
// 5、全局变量和循环
// for (let i = 0; i < 10; i++) {
// console.log(i) // 0 1 2 3 4 5 6 7 8 9
// }
for (let i = 0; i < 10; i++) {
setTimeout(function () {
console.log(i) // 0 1 2 3 4 5 6 7 8 9
})
}
选项卡案例操作:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
#container {
width: 500px;
height: 300px;
border: solid 1px #000;
overflow: hidden
}
.title {
display: flex;
justify-content: space-between;
height: 50px;
width: 100%;
border-bottom: 1px solid #000;
}
.title span {
display: inline-block;
flex: 1;
text-align: center;
line-height: 50px;
}
.title span:hover {
background: #efefef;
}
.title span.active {
background: orangered;
color: white;
}
.content {
width: 100%;
padding: 10px;
position: relative;
}
.content span {
position: absolute;
left: 0;
top: 20px;
display: none;
}
.content span.active {
display: block;
}
</style>
</head>
<body>
<div id="container">
<div class="title">
<span class="active">新闻</span>
<span>动态</span>
<span>通知</span>
</div>
<div class="content">
<span class="active">新闻内容</span>
<span>动态内容</span>
<span>通知内容</span>
</div>
</div>
<script>
function $(selector) {
return document.querySelectorAll(selector)
}
var _lis = $(".title span")
var _cts = $(".content span")
// 选项卡
// for (var i = 0; i < _lis.length; i++) {
// // 记录索引
// _lis[i].index = i
// // 单击事件
// _lis[i].onclick = function () {
// // 高亮标题
// for (var j = 0; j < _lis.length; j++) {
// _lis[j].className = ""
// }
// this.className = "active"
// // 显示内容
// for (var m = 0; m < _cts.length; m++) {
// _cts[m].className = ""
// }
// _cts[this.index].className = "active"
// }
// }
// ES6 使用let
for (let i = 0; i < _lis.length; i++) {
// let声明的变量存在块级作用域,所以不需要记录索引
// 单击事件
_lis[i].onclick = function () {
// 高亮标题
for (let j = 0; j < _lis.length; j++) {
_lis[j].className = ""
}
this.className = "active"
// 显示内容
for (let m = 0; m < _cts.length; m++) {
_cts[m].className = ""
}
_cts[i].className = "active"
}
}
</script>
</body>
</html>
② const
作用:声明常量(一旦创建不能更改)
项目开发中,原生
JS
使用var
声明的变量,在任何时候都可以进行修改;但是项目中某些数据一旦声明后续不用修改,如游戏总关卡数量、文章最大字数限制…
// 1、基础语法
const maxWords = 2000 // 常量
console.log("最大字数:", maxWords)
// maxWords = 2200 // 修改
// Uncaught TypeError: Assignment to constant variable.
// 未处理的 类型错误: 修改 了 一个常量-> 不能修改常量数据
// 2、注意:可以修改对象内部数据
// 声明了对象
const person = {
name: "文帝", age: 22 }
// person = { name: "jerry" } // 不允许:直接修改了一个新对象
// 相当于重新创建了一个对象赋值给person
// Uncaught TypeError: Assignment to constant variable.
// 未处理的 类型错误: 修改 了 一个常量-> 不能修改常量数据
person.name = "Wendy"// 允许:修改了对象的属性,没有修改对象本身
console.log(person, "person")
// 理解:给person常量赋值了一个人- 张三
// 不允许:给person常量赋值一个人- 李四
// 允许:给张三~原来是紫色衣服,修改成白色衣服
③ 总结
ES6
中针对变量使用,扩展提供了两个关键字let
、const
,是对原生JS
语法补充,并不表示原来的var
关键字过时了!
- 如果一个变量需要预解析操作,建议使用
var
声明 - 如果一个变量不需要解析器、为了避免全局污染可以使用
let
声明 - 如果一个变量一旦声明不希望被修改,可以使用
const
声明
项目中,使用const
声明常量的方式使用最多的!
面试题解析:观察下面的代码,请描述输出结果
var name = "Wendy"
function fn() {
// var name; 局部变量预解析
console.log(name) // ① undefined
var name = "jerry"
}
fn()
let username = "tom"
function fn2() {
console.log(username) // ② 报错,let声明的变量,必须先声明,后使用
let username = "shuke"
}
fn2()
3、运算符扩展
ES6
针对原来的运算符,在项目中的使用场景,扩展了两个常用的运算符
spread
延展运算符、展开运算符rest
剩余参数运算符
(1) spread延展运算符
基本语法
// 语法: ...变量,将变量中的数组/对象数据进行展开
// 经常用于变量中数据的复制
// 1、数组展开操作
let arr = [1, 2, 3, 4, 56, 7, 8, 9]
console.log