ES6 前端必学ES6,看完掌握新特性
Posted IT_Holmes
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ES6 前端必学ES6,看完掌握新特性 相关的知识,希望对你有一定的参考价值。
文章目录
1.ES6 rest 参数
ES6 引入rest参数,用来获取函数的实参,用来代替arguments。
<script>
//ES6 引入rest参数,用来获取函数的实参,用来代替arguments。
//arguments和rest参数,得到的结果不同,前者是对象,后者是数组。
function data(){
console.log(arguments);
}
data('zhangsan','lisi','wangwu');
function jiantou(...args){
console.log(args);
}
jiantou('zhangsan','wangwu','lisi');
</script>
arguments和rest参数,得到的结果不同,前者是对象,后者是数组。
见下图结果:
注意:
rest参数必须要放到参数最后。
2. ES6 扩展运算符
2.1 ES6 简介
[ … ] 扩展运算符能将数组转换为逗号分隔的参数序列。
扩展运算法和rest参数,不一样,扩展运算符常用的就是将一个数组内容,有顺序的传入到一个函数方法中。
2.2 应用
1. 数组合并
<script>
//数组合并
const s = ['1','2','3','4'];
const q = ['5','6','7','8'];
const m = [...s,...q];
console.log(m);
</script>
2. 数组克隆
<script>
//数组克隆
const a = ['zhangsan','lisi','wangwu'];
const b = [...a];
console.log(b);
</script>
3. 将伪数组转化为真正的数组
<!DOCTYPE html>
<html lang="en">
<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>
</head>
<body>
<div></div>
<div></div>
<div></div>
<script>
//这里的divs是伪数组,可以看的出它的类别是节点列表nodelist。
const divs = document.querySelectorAll('div');
console.log(divs);
//转化为数组
const divArr = [...divs];
console.log(divArr);
</script>
</body>
</html>
3. ES6 Symbol 数据类型
在ES6中,Symbol表示独一无二的值,也是ES6推出的第七种数据类型。Symbol和字符串不同!
3.1 Symbol两种创建方式
1. 直接Symbol() 来创建Symbol对象。这是通过调用函数来创建Symbol对象。
<script>
let s = Symbol();
let s2 = Symbol('张三');
let s3 = Symbol('张三');
console.log(s2 === s3);
</script>
这里的两个张三是不同的!
2. 使用Symbol.for方法来创建Symbol对象。和上面不同这是通过函数对象来创建Symbol。
<script>
let s = Symbol.for("zhangsan");
let s2 = Symbol.for("zhangsan");
console.log(s === s2);
</script>
而使用Symbol.for创建的相同值,是一样的!!
3.2 Symbol注意事项 7个数据类型
注意:
Symbol定义的变量不能与其他数据进行运算。
7个数据类型:
记忆小技巧:
USONB (you are so niubility)
u : undefined
s : String Symbol
o : Object
n : null number
b : boolean
3.3 给对象,添加Symbol的两种属性
方式一:
向对象中添加另一个对象的属性值为Symbol的方法。
<script>
let game = {
up:function(){
console.log("game");
},
down:function(){
console.log("game2");
}
};
//向game中添加methods的属性值
let methods = {
up:Symbol(),
down:Symbol()
};
game[methods.up] = function(){
console.log("我可以改变形状");
};
game[methods.down] = function(){
console.log("我可以快速下降");
};
console.log(game);
</script>
方式二:
直接使用[]添加Symbol的对象属性。
<script>
//直接使用[]添加Symbol的对象属性。
let game = {
name:"英雄联盟",
[Symbol('角色')]:function(){
console.log("我是亚索");
},
[Symbol('我哥哥是谁')]:function(){
console.log("是永恩啊");
}
}
</script>
4. Symbol 内置属性
4.1 hasInstance 与 instanceof
instanceof的用途是判断一个对象是否在某个对象原型链上。或者说判断一个对象是某个对象的实例。
当其他对象使用instanceof运算符,判断是否为对象的实例时,会调用这个方法。
例如:
<script>
class Person{
//hasInstance可以自己来控制类型检测
static [Symbol.hasInstance](param){
console.log(param);
console.log("我被用来检测类型");
};
}
let o = {};
console.log(o instanceof Person);
</script>
4.2 isConcatSpreadable 与 concat
对象的Symbol.isConcatSpreadable属性等于的是一个布尔值,表示该对象用于concat(Array.prototype.concat())时,是否展开。
<script>
const arr = [1,2,3];
const arr2 = [4,5,6];
//通过设置isConcatSpreadable来决定,合并后是否展开。
arr2[Symbol.isConcatSpreadable] = false;
console.log(arr.concat(arr2));
</script>
4.3 其他Symbol的内置属性
这些属性都是Symbol的内置属性,而他们的整体来作为对象的属性去设置,来改变对象在特定场景下面的表现。
5. 迭代器
迭代器(Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制。 任何数据结构只要部署了Iterator接口,就可以完成遍历操作。
在ES6中,一个新的遍历命令for … of循环,iterator接口主要供for … of 来使用。
以下的数据都可以使用for … of :
注意:
for in 遍历的是键名。
for of 遍历的是键值。
<script>
const a = ['英雄联盟','穿越火线','CSGO'];
//使用for in 和for of来遍历。
//for in 遍历的是键名
for(let b in a){
console.log(b);
}
//for of 遍历的是键值
for(let c of a){
console.log(c);
}
console.log(a);
</script>
可以自己打印一下,查看Iterator的接口:
Iterator (迭代器)的工作原理:
关键是看next指针,我们可以打印第一个next指针看看。
<script>
const a = ['英雄联盟','穿越火线','CSGO'];
let iterator = a[Symbol.iterator]();
//打印一下迭代器,看看有什么内容
console.log(iterator)
//打印第一个next的内容值
console.log(iterator.next());
//打印第二个next的内容值
console.log(iterator.next());
//打印第三个next的内容值
console.log(iterator.next());
//没有内容时,就是显示undefined,并且done对象显示true,表示已经完成。
console.log(iterator.next());
</script>
6. 迭代器自定义遍历对象
通过使用迭代器自定义遍历数据,自定义就是按照自己的想法来遍历对象或者对象内的数据。
例如:
<!DOCTYPE html>
<html lang="en">
<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>
</head>
<body>
<script>
const a = {
name:"zhangsan",
status:[
'jiankang',
'shengbing',
'touteng',
'ganmao'
],
//给对象声明iterator接口方法
[Symbol.iterator](){
//声明索引变量
let index = 0;
return {
next:() => {
if(index < this.status.length){
const result = {value:this.status[index],done:false};
//下标自增
index++;
return result;
}else{
return {value: undefined,done:true};
}
}
}
}
}
//遍历status中的内容。
for(let v of a){
console.log(v);
}
</script>
</body>
</html>
7. ES6 生成器(异步编程)
7.1 生成器 简介
生成器其实就是一个特殊的函数,主要作用就是异步编程。
生成器,加上“ * ” 号。
调用next()方法来打印下面案例:
<script>
//生成器,加上“ * ” 号。
function * gen(){
console.log("你好。");
}
let ing = gen();
// 这样的函数,普通的console.log()打印是不行的,必须调用next()方法才可以。
//为什么调用next方法呢,可以打印一下ing,查看他的结构。
ing.next();
</script>
7.2 生成器 yield
yield可以算作是函数代码的分隔符。
<script>
//生成器,加上“ * ” 号。
function * gen(){
//yield可以算作是函数代码的分隔符。
console.log("第一块领域");
yield '我分割了第一块领域和第二块领域。';
console.log("第二块领域");
yield '我分割了第二块领域和第三块领域。';
console.log("第三块领域");
yield '我分割了第三块领域和第四块领域。';
console.log("第四块领域");
}
let i = gen();
//这里yield的作用体现出来了,就可以一一进行执行。
i.next();//执行一块领域
i.next();//执行二块领域
i.next();//执行三块领域
i.next();//执行四块领域
</script>
也可以打印i.next()方法,来查看对象value和done的值。如下:
<script>
//生成器,加上“ * ” 号。
function * gen(){
//yield可以算作是函数代码的分隔符。
console.log("第一块领域");
yield '我分割了第一块领域和第二块领域。';
console.log("第二块领域");
yield '我分割了第二块领域和第三块领域。';
console.log("第三块领域");
yield '我分割了第三块领域和第四块领域。';
console.log("第四块领域");
}
let i = gen();
//这里yield的作用体现出来了,就可以一一进行执行。
console.log(i.next());//执行一块领域
console.log(i.next());//执行二块领域
console.log(i.next());//执行三块领域
console.log(i.next());//执行四块领域
//也可以打印i.next()方法,来查看对象value和done的值。
</script>
7.3 生成器函数参数
生成器的参数大体分为两种,正常的携带参数 和 next方法传入实参。
<!DOCTYPE html>
<html lang="en">
<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>
</head>
<body>
<script>
function * gen(arg){
console.log(arg);
let one = yield '111';
console.log(one);
let two = yield '222';
console.log(two);
let three = yield '333';
console.log(three);
}
//正常的携带参数
let iter = gen('AAA');
console.log(iter.next());
//next方法是可以传入实参的!
//这里传入的BBB将作为第一个yield语句的返回结果,我们在上面打印了一下yield '111',查看结果。
console.log(iter.next('BBB'));
//这里传入的CCC将作为第二个yield语句的返回结果。
console.log(iter.next('CCC'));
//这里传入的DDD将作为第三个yield语句的返回结果。
console.log(iter.next('DDD'));
</script>
</body>
</html>
7.4 生成器的使用
使用生成器来依次那个调用相应函数的案例,来表现异步编程思想。
案例一:简单的异步
<!DOCTYPE html>
<html lang="en">
<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>
</head>
<body>
<script>
let one = ()=>{
setTimeout(()=>{
console.log("一秒后。");
iter.next();
},1000)
}
let two = ()=>{
setTimeout(()=>{
console.log("二秒后。");
iter.next();
},2000);
}
let three = ()=>{
setTimeout(()=>{
console.log("三秒后。");
iter.next();
},3000);
}
//使用生成器来依次那个调用上面函数的案例
function * gen(){
yield one();
yield two();
yield three();
}
let iter = gen();
iter.next();
</script>
</body>
</html>
案例二:next携带参数的异步
<!DOCTYPE html>
<html lang="en">
<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>
</head>
<body>
<script>
let getUser = ()=>{
setTimeout(()=>{
let data = "用户数据";
//调用next方法,并且将数据传入
这里的data将作为第一个yield返回的结果
iter.next(data);
},1000);
};
let getOrders = ()=>{
setTimeout(()=>{
let data = "订单数据";
//这里的data将作为第二个yield返回的结果
iter.next(data)
},1000);
};
let getGoods = ()=> {
setTimeout(()=>{
let data = "商品数据";
//这里的data将作为第三个yield返回的结果
iter.next(data);
},1000);
};
function * gen(){
let users = yield getUser();
console.log(users);
let orders = yield getOrders();
console.log(orders);
let goods = yield getGoods();
console.log(goods);
}
let iter = gen();
iter.next();
</script>
</body>
</html>
以上是关于ES6 前端必学ES6,看完掌握新特性 的主要内容,如果未能解决你的问题,请参考以下文章