ECMAScript概念
ECMAScript 也是一门脚本语言 缩写 ES
通常看作为JavaScript 的标准化规范
实际上JavaScript 是ECMAScript 的扩展语言
因为 ECMASscript 只提供了最基本的语法
在浏览器中 JavaScript = ECMAScript + Web APIs (BOM , DOM 等)
在NodeJs中 JavaScript = ECMAScript + Node APIs(fs, net, etc. 等)
所以可以说 JavaScript 语言本身指的就是 ECMAScript
从2015年开始 ECMAScript 保持每年一个版本迭代
ECMAScript2015 又被称为 ES6
1.相比上一个版本 ES5.1变化比较大 相差5年
2.命名规则发生了变化
*有些开发人员把ES2015以后的所有新特性统称为ES6
ES2015 在 ES5.1基础之上的变化
1.解决原有语法上的一些问题或者不足 例如 let const 所提供的块级作用域 等
2.对原有语法进行增强 例如 解构 展开 参数默认值 模板字符串 等
3.全新的对象,全新的方法,全新的功能 例如 Promise 等
4.全新的数据类型和数据结构
(一)let 块级作用域 与 const
作用域 – 某个成员能够起作用的范围 es2015 之前 ES中只有两种作用域 分别是 全局作用域 和 函数作用域。ES2015中新增 块级作用域 {}
let 声明的变量只能在块级作用域 {} 内部 访问到 外部无法访问
1. 块级作用域例子:模拟注册onclick事件 然后获取注册时的值
var elements = [{
}, {
}, {
}]
for(var i = 0; i < elements.length; i++){
elements[i].onclick = function(){
console.log(i)
}
}
elements[1].onclick() // 3 <-- 预期是 1 此时 i 位于全局作用域中 无论怎么获取 都是3
在 es2015之前 使用闭包解决这个问题, 因为没有块级作用域 只有全局和函数作用域, 所以创建函数限制访问范围
var elements = [{
}, {
}, {
}]
for(var i = 0; i < elements.length; i++){
(function(i){
elements[i].onclick = function(){
console.log(i)
}
})(i)
}
elements[1].onclick() // 1
在 es2015之后,使用let 块级作用域解决这个问题
var elements = [{
}, {
}, {
}]
for(let i = 0; i < elements.length; i++){
elements[i].onclick = function(){
console.log(i)
}
}
elements[1].onclick() // 1
2. for循环内部块级作用域嵌套
for(let i = 0; i < 3; i++){
let i = 'hello world'
console.log(i) // hello world <--- 这里的 i 为什么没有赋值的冲突
}
因为for循环的 i 与内部的i不在一个块级作用域。拆分这个for循环得到以下代码
let i = 0
if(i < 3){
let i = 'hello world'
console.log(i)
}
i++
第一个声明的 i 的作用域在外部,第二个声明的 i 的作用域在 if 内部。所以不会冲突
3. const (恒量/常量):在let的基础之上多了 [只读]
const msg = 'hello world'
msg = '你好' // TypeError: Assignment to constant variable.
// const 声明的常量 不可以修改(不能修改内存地址,不能修改值类型)
const msg1 // SyntaxError: Missing initializer in const declaration
msg1 = 'hello world'
// const 声明时 必须初始化
const obj = {
}
obj.name = '张三'
// const声明的对象可以修改属性
ES2015之后的最佳实践: 不用var,主要用const,配合使用let
(二)数组的解构
const users = ['张三','李四','王五']
const [user1, user2, user3] = users
console.log(user1 + user2 + user3) // 张三李四王五
// 当只需要指定下标的元素时,空出其他声明
const [, , user4] = users
console.log(user4) //王五
// 使用...解构剩余的所有元素,变成数组
const [user5, ...userArray] = users
console.log(userArray) //[ '李四', '王五' ]
//解构时声明的变量超出数组长度为undefined
const [user6, user7, user8, user9] = users
console.log(user9) //undefined
//直接给声明的变量赋值,当没有解构到数据时,输出赋值的数据,反之输出解构的数据
const [user10, user11, user12 = '田七', user13 = 'default value'] = users
console.log(user12) //王五
console.log(user13) //default value
//例子,分割字符串取出下标为1的数据
const path = '/window/学习资料/index.js'
const[, name] = path.split('/')
console.log(name) //window
(三)对象的解构
const user = {
name:'张三', age:18 }
const {
name } = user
console.log(name) //张三
//当解构时声明的变量与其他变量名冲突时 使用 :重命名变量
const age = 20
const {
age: age1} = user
console.log(age1) // 18
//例子 解构常用函数 console.log
const {
log } = console
log('message') //message
(四)模板字符串 `` 和 新的字符串扩展方法
const str = `hello world`
//使用插值表达式 ${} 插入js代码
const name = `张三`
const msg = `${
name}:今天是${
new Date().getDate()}号`
console.log(msg) //张三:今天是8号
带标签的模板字符串 :在模板字符串之前加函数
console.log`hello world` // [ 'hello world' ] 返回值是数组
函数的参数为字符串中根据差值表达式分割后的字符串数组,和所有插值表达式
const name = '张三'
const gender = false
function strTagFunc(strings, name, gender){
const sex = gender ? 'body' : 'girl'
return strings[0] + name + strings[1]