带你了解ES6中的一些新特性
let 和 const
let: 声明的变量只有在let命令下的代码块有效,也叫块级作用域
const: 声明的变量是只读的,一旦声明常量的值就不能改变,
但是如果用const来声明数组或者对象,则数组,对象下的值可以改变,原因是const指向的变量的地址没有发生改变
let 和 var的区别
let
是在代码块内有效,var
是全局范围有效let
只能声明一次,var
可以多次声明;let
不存在变量提升,但有作用域链
解构赋值
从数组和对象中提取值,对变量进行赋值,称为解构赋值
- 基本的数组对数组赋值
let [a,b,c] = [1,2,3];//a=1,b=2,c=3
- 采用剩余运算符
let [a,...b] = [1,2,3];//a=1,b=[2,3]
剩余运算符表示用b来接收之后的所有值,所以返回数组
- 字符串解构
let [a,b,c,d,e] = 'hello';//hello
将字符串拆分成一个个字符来赋值,将字符串转化为对象
- 对象解构赋值
let {foo, bar} = { foo: 'aaa',bar: 'bbb'};
console.log(foo);//aaa
console.log(bar);//bbb
- 变量名和属性名不一致
let { baz : foo} = {baz : 'ddd'}
console.log(foo);//ddd
console。log(baz);undefind
baz
是模式,foo
才是值,在解构的时候,内部会先寻找同名的属性,赋值给他,所以这里是foo
接收到了ddd
解构赋值应用
交换变量
var a = 1;
var b = 2;
[a,b] = [b,a];
接收返回值
function fn() {
return [1,2,3];
}
var [a,b,c] = fn();
获取json对象中的数据
var data = {
name : 'ljc',
age : 20
}
var {name,age} = data;
console.log(name + age);//ljc20
部分赋值
var ljc=[1,2,3];
var [,x,]=ljc;
console.log(x);//2
var obj = {x : 1,y : 2, z : 3};
var {y : a} = obj;
console.log(a);//2
模板字符串
- 引入方式为【``】
console.log(`hello world`);
- 使用模板字符串表示多行字符串,所有的空格和缩进都会被保留在输出之中。
let str = `<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>`;
- 变量拼接
模板字符串中嵌入变量,需要将变量名写在
${}
之中
let lovest = 'ljc';
let out = `${lovest}最帅`;
console.log(out);//ljc最帅
- 模板字符串调用函数
function fn () {
console.log('我是ljc');
}
let out = `${fn()}`;//我是ljc
对象的简化写法
省略同名的属性值,省略方法的function
const name = 'ljc';
const age = 20;
const my = {
name,
age,
say() {
console.log('我是' + name + '今年' + age);
}
}
my.say()//我是ljc,今年20
箭头函数
//ES6
let res = () => {
let a = 3;
console.log(a);
}
//ES5
var rel = function() {
var b = 2;
console.log(b);
}
res();//3
rel();//2
- 没有参数时,小括号不能省略
let say = () => {
console.log('ljc');
}
say();//ljc
- 当有一个参数时,小括号可以省略:
let test = a => {
console.log(a);
}
test('我是ljc');//我是ljc
- 当参数大于1个时,小括号不能省略 ()=>{}
let test = (a,b) => {
console.log(a + b);
}
test(2,3);
- 当后面只有一条语句时,大括号可以省略 ,返回值就是这条语句
let say = () => console.log('ljc');
say();//ljc
-
箭头函数的 this 指向定义时所在的对象
-
箭头函数没有原型
-
箭头函数不可以作为构造函数(即不能使用 new)
-
箭头函数没有 arguments 对象
rest参数
返回值是一个数组,rest参数必须要放到参数最后
function date(...args) {
console.log(args);
}
date('l','j','c');//['l','j','c']
扩展运算符
将一个数组转化成用逗号分隔的参数列表
function add(x,y) {
return x + y;
}
let num = [1, 2];
add(...num)//3
应用
function push(array, ...rest) {
array.push(...rest);//这个是扩展运算符,将...rest转化成参数列表
}
let arr =[1,2];
push(arr,3,4,5);
console.log(arr);//[1,2,3,4,5]
Symbol
Symbol能够产生独一无二的值,避免与之前的代码产生覆盖。
传入一个值,作为描述字符串,更好的理解这个值的作用
无论传入的值,参数名是否相同,都是独一无二的
let s1 = Symbol();
let s2 = Symbol();
console.log(typeof s1);// symbol
console.log(s1 === s2); // false
symbol.for创建
let s4 = Symbol.for('ljc');
let s5 = symbol.for('ljc');
console.log(s4 === s5);//true
通过这种方法创建的是可以通过描述字符串得出唯一的symbol
不能与其他数据进行运算
作为属性名
let mySymbol = Symbol();
var a = {};
a[mySymbol] = 'Hello!';
console.log(a);//{ symbol(): 'Hello!' }
Symbol值作为属性名要使用方括号定义,不能使用点运算符
Symbol作为属性名遍历
var obj = {}
var a = Symbol('a')
var b = Symbol('b')
obj[a] = 'a'
obj[b] = 'b'
Object.getOwnPropertySymbols(obj)
//[Symbol(a), Symbol(b)]
使用Reflect.ownKeys可以遍历Symbol的键名
var a = Symbol('a');
var b = Symbol('b');
var obj = {
foo: 1
}
obj[a] = 1;
obj[b] = 2;
Reflect.ownKeys(obj);
//["foo", Symbol(a), Symbol(b)]
迭代器
迭代器(Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署迭代器接口,就可以完成遍历操作。
Iterator接口主要提供for…of消费
工作原理
- 创建一个指针对象,指向当前数据的起始位置,返回一个对象(有next方法)
- 第一次调用对象的next方法,指针指向数据的第一位
- 不断的调用next方法,指针一直向下一位移动,直到指向undefind
- 每调用next方法返回一个包含value和done属性的对象
const my = ['ljc','20','men'];
for(let a of my) {
console.log(a);
}//ljc 20 men
利用迭代器思想 自定义遍历对象
const my = {
name: 'ljc',
age: '20',
like: ['rose','SaLah','BlackPink'],
[Symbol.iterator]() {
let index = 0;//索引变量
let _this = this;//保存this指向
return {
next: function() {
if(index < _this.like.length) {//判断是否结束
const result = {
value: _this.like[index],//指向下一个
done: false
}
index++;
return result;
}else {
return {
value: undefined,
done: true
}//结束
}
}
}
}
}
for(let k of my) {
console.log(k);
}
生成器
拥有在一个函数块内暂停和恢复代码执行的能力
生成器的形成是一个函数,函数名称前面加一个
*
表示它是一个生成器
/* 生成器函数的声明 */
function* gen() {}
/* 表达式 */
let gen = function* () {}
/* 作为对象字面量方法的生成器 */
let foo = {
*gen() {}
}
-
箭头函数不能用来定义生成器函数
-
星号的位置不影响生成器
调用生成器对象函数会产生一个生成器对象。生成器一开始处于暂停状态,与迭代器相似,生成器对象也实现了iterator
接口,具有next方法。因此可以通过调用这个方法来控制生成器的开始或恢复执行
yield中断执行
yield
可以让生成器停止或开始执行。生成器函数在遇到yield关键字之前会正常执行。遇到yield
后会暂停,通过next方法恢复
function * gen() {
yield;
}
let genObj = gen();
console.log(genObj.next());// {value: undefined, done: false} yield
console.log(genObj.next());// {value: undefined, done: true} end
生成器对象作为可迭代对象
function* gen() {
yield 1;
yield 2;
yield 3;
}
for(const x of gen()) {
console.log(x);
}//1 2 3
注意gen要带括号才是对象
使用yield实现输入输出
yield关键字可以作为函数的中间参数使用。上一次生成器函数暂停的yield会接收到传给next()方法的第一个值。也就是说第一个调用next传入的值不会被使用
function * gen(arg) {
console.log(arg);//11
console.log(yield 111); //我是第二个next
console.log(yield 222);//我是第三个next
console.log(yield 333);//我是第四个next
}
let iterator = gen(11);
iterator.next('我是第一个next');//启用生成器
iterator.next('我是第二个next');
iterator.next('我是第三个next');
iterator.next('我是第四个next');
产生可迭代对象
可以使用星号增强yield行为,让它能够迭代一个可迭代对象,从而一次产生一个值
//未增强yield
function * gen() {
yield [1, 2, 3];
}
let genObj = gen();
console.log(genObj.next());//[1, 2, 3]
//增强yield
function * gen() {
yield * [1, 2, 3];
}
let genObj = gen();
for(const x of gen()) {
console.log(x);
}// 1 2 3
- 点赞
- 收藏
- 关注作者
评论(0)