前端之ES6语法
- 1. ES6简介
- 2. ES6新特性
- 3.ES6不支持,使用babel
- 3.1 参考文献
- 4.let和const命令
- 5. 模版字符串
- 6.函数之默认值、剩余参数
- 7. 函数之扩展运算符、箭头函数
- 8.箭头函数this指向和注意事项
- 9.解构赋值
- 10.对象扩展
- 11.Symbol类型
- 12.Set集合类型
- 13.Map数据类型
- 14.数组的扩展_1
- 15.数组的扩展_2
1. ES6简介
- ES5语言的先天性不足。比如变量提升、内置对象的方法不灵活、模块化实现不完善等
- 为了后面vue、尤其是react框架做好了准备
- 目前大部分公司的项目都在使用es6
ECMAScript6.0(l以下简称ES6)是JavaScript语言的下一代标准,已经在2015年6月正式发布了。它的目标,是使得JavaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语言。
ES6既是一个历史名词,也是一个泛指,含义是5.1版以后的JavaScript的下一
代标准,涵盖了ES2015、ES2016、ES2017等等,而ES2015则是正式名称,特
指该年发布的正式版本的语言标准。
2. ES6新特性
- let和const命令
- es6的模板字符串
- 增强的函数
- 扩展的字符串、对象、数组功能
- 解构赋值
- Symbol
- Map和Set
- 迭代器和生成器
- Promise对象
- Proxyi对象
- async的用法
- 类class
- 模块化实现
各大浏览器的最新版本,对ES6的支持可以查看 点我,随着时间的推移,支特度已经越来越高了,超过90%的ES6语法特性都实现了。
3.ES6不支持,使用babel
- 被称为下一代的JavaScript编译器。可以将es6的代码转换成es5的代码,从而让浏览器获得支特
- 这个课程我们只需要知道前端工具babe这个工具的作用,在这里不做过多的赘述
- 这里不讲解babel,只讲述es6语法
3.1 参考文献
- ES6阮一峰教程 http://es6.ruanyifeng.com
- MDN https://developer.mozilla.org/zh-CN/docs/Web/JavaScript
4.let和const命令
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>let_const</title>
</head>
<body>
<script>
// var
// console.log(a) //输出 undefined
// var a = 2;
// a = 2;
//1.let声明变量, 没有变量提升,报错
// console.log(a)
// let a = 2;
//2.是一个块级作用域,报错:Uncaught ReferenceError: b is not defined
// console.log(b)
// if(1==1) {
// let b = 10;
// }
// 3. let不能重复声明(Uncaught SyntaxError: Identifier 'c' has already been declared )
// let c = 1;
// let c = 2;
// 4.const定义变量,不能重新修改
const NAME = "热爱学习编程";
// NAME = "我不喜欢学习"; // 直接报错
// 5.const修饰的对象,只能修改其属性,不能对对象重新赋值。
const obj = {
name: "张三",
age: 18
}
// 可以
obj.age = 19;
// 不可以
/* obj = {
name: "李四",
age: 20
}
*/
const arr = [];
for(let i = 0 ; i <10; i++) {
arr[i] = function(){
return i;
}
}
console.log(arr[5]()) // 输出10,不对呀,不应该是5吗?
/*解决方法: 使用let*/
// 不会污染全局变量
let RegExp = 10;
console.log(RegExp)
console.log(window.RegExp)
/*
* 建议:在默认情况下用const;
* 而只有你知道变量会改变值的时候,用let.
*/
</script>
</body>
</html>
5. 模版字符串
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模版字符串</title>
</head>
<body>
<div class="box">
</div>
<script>
// 模板字符串:使用tab键上面的反引号``,插入变量时使用$(变量名)
const oBox = document.querySelector('.box');
let id = 1,name = "ypy";
// 麻烦版本
// oBox.innerHTML = "<ul><li><p id="+id+">" +name+ "</p></li></ul>";
// 方便版本
oBox.innerHTML = `
<ul>
<li><p id=${id}>${name}</p></li>
</ul>
`
</script>
</body>
</html>
6.函数之默认值、剩余参数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>函数默认参数_剩余参数</title>
</head>
<body>
<script>
// es5
/*function add(a,b) {
a = a || 10;
b = b || 20;
return a+b;
}*/
// console.log(add()); // 30
function add(a = 10, b = 20) {
return a + b;
}
console.log(add())
console.log("-----------------------")
//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;
}
const book = {
title: 'es6教程'
,author:'yeskip'
,year:'2019'
}
let bookData = pick(book,'author','year')
console.log(bookData)*/
// 剩余参数:由三个点,和一个紧跟着的具名参数指定 ...keys
// 解决了argument的问题
function pick(obj, ...keys) {
let result = Object.create(null);
for (let i = 0; i < keys.length; i++) {
result[keys[i]] = obj[keys[i]];
}
return result;
}
const book = {
title: 'es6教程'
,author:'yeskip'
,year:'2019'
}
let bookData = pick(book,'author','year')
console.log(bookData)
</script>
</body>
</html>
7. 函数之扩展运算符、箭头函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>扩展运算符_箭头函数</title>
</head>
<body>
<div></div>
<script>
// 剩余参数:把多个独立的参数,合并成一个数组
// 扩展运算符:把数组展开成独立的参数,并将值作为参数传递给函数
const maxNum = Math.max(20, 30)
console.log(maxNum)
// 处理数组的最大值,使用apply
const arr = [10, 20, 30, 40, 50, 60, 70, 100]
console.log(Math.max.apply(null, arr))
// 使用es6扩展运算符
const maxNumber = Math.max(...arr);
console.log("maxNumber=", maxNumber)
console.log("--------------------------------")
//箭头函数
/*
* 使用=> 定义 function(){} 等价于 () => {}
*/
let addWithArrow = (a,b) => a+b;
console.log("arrow function compute result: ",addWithArrow(1, 2));;
/*let getId = id => {
return {
id: id,
name: "小袁子"
}
}*/
// ===》 等价于
let getId = id => ({id: id, name: "小袁子"});
let obj = getId(1)
console.log(obj)
// 闭包函数
/*
声明一个函数fun1,此函数fun1返回一个函数fun2,执行fun1()
*/
let fn = (function() {
return function() {
console.log("hello es6");
}
})();
fn();
let fnWithArrow = () => (function(){console.log("hello es6 with arrow!")})()
let fnWithArrow2 = (()=>{
return ()=>{
console.log("hello es6 with arrow!!!")
}
})();
// fnWithArrow();
fnWithArrow2();
</script>
</body>
</html>
8.箭头函数this指向和注意事项
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>箭头函数需要注意</title>
</head>
<body>
<script>
// this指向,没有
// es5中this指向,取决于该函数的上下文对象
// function.bind() 是将function绑定到其他对象身上的做法,绑定到参数上的this
let PageHandle = {
id: 123,
init: function (){
document.addEventListener('click', function (event){
//Uncaught TypeError: this.doSomething is not a function
// this => document
this.doSomething(event.type);
}.bind(this), false);
},
doSomething: function (type) {
console.log(`事件类型: ${type},当前id: ${this.id}`)
}
}
// PageHandle.init();
// 使用箭头函数
let pageHandler = {
id: 123,
init: () => {
// 箭头函数是没有this指向的,箭头函数内部this值只能通过查找作用域链来确定,
// 一旦使用箭头函数,当前就不存在作用域链,全部没有的话,就找到了window对象
document.addEventListener('click', (event) => {
//Uncaught TypeError: this.doSomething is not a function
// this => document
this.doSomething(event.type);
});
},
doSomething: function (type) {
console.log(`事件类型: ${type},当前id: ${this.id}`)
}
}
pageHandler.init();
// 如果上边的pageHandler.init定义方法都是箭头函数,那么就会找到这一层的scope
function doSomething(type) {
console.log(`this is window scope. ${type}`);
}
// 使用箭头函数注意事项
/*
* 1.使用箭头函数的注意事顶1:使用箭头函数函数内部没有arguments
*/
// let getVal = (a, b) => {
// console.log(arguments)// 没有作用域了,相应的argument也不在
// return a + b;
// }
// console.log(getVal(1, 3))
let getVal2 = function (a, b) {
console.log(arguments)
return a + b;
}
console.log(getVal2(5, 8));
// 箭头函数能使用new关键字实例化对象
// let Person = ()=> {
//
// }
// 这样可以创建new Person
let Person = function(a,b) {
return {
age: a,
name: b
}
}
// function函数也是一个函数,但是箭头函数不是一个对象,其实就是一个语法糖(表达式)
let p = new Person(11,"tom");
console.log(p)
</script>
</body>
</html>
9.解构赋值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>解构赋值</title>
</head>
<body>
<script>
// 解构赋值是对赋值运算符的一种扩展
// 它针对数组和对象来进行操作
// 优点: 代码书写上简洁易读
let node = {
type: 'iden',
name: 'foo'
}
// 完全解构
let {type, name} = node;
console.log(type, name)
let obj = {
a: {
name:"张三"
},
b:[],
c:"hello world"
}
// 不完全解构
let {a,b,c} = obj;
// console.log(a)
// console.log(b)
// console.log(c)
// 剩余运算符,起别名
let {a:ss,...res} = obj;
// console.log(aa,res)
console.log(ss)
console.log(res)
// 数组解构
let arr = [1,2,3]
let [t,m,p] = arr;
console.log(t,m,p)
// 嵌套
let [r,[w],v] = [12,[13],49];
console.log(r,w,v)
</script>
</body>
</html>
10.对象扩展
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>扩展的对象</title>
</head>
<body>
<script>
const name = "yeskip", age = 20;
const person = {
name: name, age: age, sayName() {
}
}
// 对象扩展
const person1 = {
name, // 等价于name:name
age, // 等价于age:age
sayName() {
console.log(this)
console.log(this.name)
}
}
person1.sayName();
// 特殊的写法
const names = 'a'
const obj = {
isShow: true,
['f' + names]() {
console.log(this)
},
[names + 'bc']: 123
}
console.log(obj)
// is() 比较两个对象严格相等 assign()
console.log(Object.is(NaN, NaN));
console.log(NaN === NaN);
// assign对象的合并
let target = {}
let obj1 = {name: '李四'}
let obj2 = {age: 34}
Object.assign(target, obj1, obj2)
console.log(target)
</script>
</body>
</html>
11.Symbol类型
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>symbol类型</title>
</head>
<body>
<script>
// 原始数据类型 Symbol,它表示独一无二的值
// 最大的用途:用来定义对象的私有变量
const name = Symbol('name')
const name2 = Symbol('name')
console.log(name === name2)
let s1 = Symbol('s1');
console.log(s1)
let obj = {
[s1]:'小袁'
}
//let obj = {}
// obj[s1] = '小袁'
console.log(obj)
// 如果用symbol定义的对象中的变量,取值时一定要用[变量名]
console.log(obj[s1])
console.log("obj对象所有的keys:"+Object.keys(obj)); // 看不到
// 获取自己的属性获取
let s = Object.getOwnPropertySymbols(obj);
console.log(s)
// 反射获取
let m = Reflect.ownKeys(obj);
console.log(m)
console.log(m[0])
console.log(obj[m[0]])
</script>
</body>
</html>
12.Set集合类型
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Set集合类型</title>
</head>
<body>
<script>
// 集合
let set = new Set();
set.add("张三")
set.add(12)
set.add(123)
// set.delete(12)
// 校验某个值是否在集合set中
let exist = set.has(`张三`);
// console.log(exist)
// console.log(set)
// 集合长度
// console.log(set.size);
set.forEach((item, index) => {
console.log(item, index)
})
// 将set转换为数组,扩展运算符
let arr = [...set]
console.log(arr)
//了解即可 1.set中对象的引用无法被释放
let set3 = new Set(),obj1 = {}
set3.add(obj1)
obj1 = null;
console.log(set3) // 还存在一个元素,无法释放
// 使用弱引用
let set4 = new WeakSet(),obj2 ={name:"张三"};
set4.add(obj2)
obj2 = null;
console.log(set4)
// WeakSet
// 1. 不能传入非对象类型的参数
// 2. 不可迭代
// 3. 没有forEach()
// 4. 没有size属性
</script>
</body>
</html>
13.Map数据类型
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Map数据类型</title>
</head>
<body>
<script>
let map = new Map();
map.set("name", "张三")
map.set("age", 12)
map.set([0, 1, 2], "hello");
let map2 = new Map([['1', 2], ['3', 4]]);
console.log("map2:", map2)
console.log(map)
let existAge = map.has("age");
console.log(existAge)
map.forEach((value, key) => {
console.log(key, value)
})
// 删除key为name的项
map.delete("name")
//清空map
map.clear()
let weakMap = new WeakMap();
</script>
</body>
</html>
14.数组的扩展_1
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>数组的扩展</title>
</head>
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<script>
// 数组的方法 from() of()
// from() 将伪数组转换为真正的数组
function add() {
let args = Array.from(arguments)
console.log(args)
}
add(1, 2, 3)
// from应用
let lis = Array.from(document.querySelectorAll('li'));
console.log(lis)
// 扩展运算符
let les = [...document.querySelectorAll('li')]
console.log(les)
// from 接收第二个参数,用于对每个元素进行处理
let list = [1, 2, 3]
let newList = Array.from(list, ele => ele ** 2);
console.log(newList)
// of将一组值转换为一个数组(将任意类型的数据转为一个数组)
let arr2 = Array.of(3, 11, 20, '30', {id: 12})
console.log(arr2)
// 3.copywithin()
// 从3位置往后的所有数值,替换从0位置往后的三个数值
console.log([0, 1, 2, 4, 5, 6, 7, 8, 9].copyWithin(0, 3));
// find findIndex()
// find 找出第一个符合条件的数组成员
// findIndex找出第一个符合条件的数组成员索引
let number = [1, 2, -10, 5, -8].find(n => n < 0);
let index = [1, 2, -10, 5, -8].findIndex(n => n < 0);
console.log(number,index)
</script>
</body>
</html>
15.数组的扩展_2
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>数组的扩展2</title>
</head>
<body>
<script>
// entries() keys() values() 返回一个遍历器,可以使用for...of循环遍历
let arr = [1,2,3,4]
let entries = arr.entries();
let keys = arr.keys();
let values = arr.values();
for (let key of keys) {
console.log(key)
}
for (let value of values) {
console.log(value)
}
for (let [index,ele] of entries) {
console.log(index + "==> " + ele)
}
// 还可以使用遍历器下一部分讲
// includes()返回一个布尔,表示某个数组是否包含给定值
console.log([12,56,55].includes(12))
console.log([12,56,55].includes(51))
</script>
</body>
</html>