ES6-let关键字的特性:
1.用let声明变量不能重复 2.let声明变量没有变量提升 3.遵循作用域链 4.具有块级作用域
ES6-const关键字特性:
1.必须要赋值
2.一般为常量赋值需要大写
3.赋值后不能修改(对象和数组修改除外,因为对象和数组只是改里面的内容 保存变量的地址值并没有变)
4.具有块级作用域
一般来说const关键字是声明数组以及对象专用
ES6-变量及对象的解构赋值:
以后遇到方法的频繁调用和数组元素的调用,就可以使用解构赋值;之前调用对象里的方法是通过对象.方法()的形式调用,通过结构赋值就可以直接调用 方法名()
要注意的是:数组的解构用[],对象的解构用{},对象解构时let里的变量名和const里的变量名相同
const _person= {
name: ‘qcq’,
age: 24,
setName: _function(){
console.log (‘HELLO’)
}
}
let {name , age , setName} = person
setName ()
const _aa= [1,2,3,4,5]
_let [a,b,c,d,e] =aa
console.log(a+b+c+d+e)
ES6-简化对象和函数写法:
ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法(在对象里面声明方法直接写方法名就可以)。这样的书写更加简洁;
let _name=’qcq’
_let _setName=_function(){
console.log(‘HELLO’)
}
_const _person = {
name,
setName,
setAge (){
console.log(‘我24了’)
}
}
person.setName()
person.setAge()
ES6-模板字符串``:
1.字符串中间有空格和换行不会报错 2.在模板字符串中使用${}拼接 在花括号中写入需要拼接的变量
_let_name=’qcq’
console.log(我叫${name})
ES6-箭头函数:
- 如果形参只有一个,则小括号可以省略;函数语句只有一句return时,花括号和return都可省略,函数的返回值为该条语句的执行结果。
2. 箭头函数 this 是静态的,指向声明时所在作用域下 this 的值(原因是箭头函数内部根本没有自己的this,它内部的this 其实就是外层代码块的 this,也就是定义时所在环境中的this对象 )。
3. 箭头函数不能作为构造函数实例化;
4. 不能使用 arguments;
使用场景:
箭头函数适合与 this 无关的回调. 定时器, 数组的方法回调
箭头函数不适合与 this 有关的回调. 事件回调, 对象的方法
//案例将偶数输出
const _array= [100,5,6,7,9,4]
console.log (array.filter(_item=>item%2===0))
call()、apply()、bind()等方法不能改变箭头函数中this的指向
var id = ‘Global’; let fun1 = () => { console.log(this.id) }; fun1(); // ‘Global’ fun1.call({id: ‘Obj’}); // ‘Global’ fun1.apply({id: ‘Obj’}); // ‘Global’ fun1.bind({id: ‘Obj’})(); // ‘Global’
ES6-默认值和解构赋值的结合:
如果实参中没有传address的值那么 address的值默认由形参中给定
function _person({_name,age,address=’宝鸡’}){
return 我叫${name}我今年${age}我家住在${address}
}
console.log(person({
name:’qcq’,
age:24
}))
ES6-rest参数:
是放在形参里的,一般放在最后一个参数,它将所传的实参转成真正的数组
function_rest(_a,…b){
returnb
}
console.log(rest(1,2,3))
这一点经常用于获取函数的多余参数,或者像上面这样处理函数参数个数不确定的情况。多用于react中给组件传递参数
ES6-[…]扩展运算符:
将数组转化成以逗号分隔的参数序列
arguments中只有一个参数,读取时arguments[0][2]必须是0在前面
而用扩展运算符传可以将数组元素全部传进去,相当于setName(qcq,24,宝鸡),读取时 arguments[2]
_const_array= [‘qcq’,24,’宝鸡’]
_function_setName(){
returnarguments[2]
}
// console.log(setName(array))
console.log(setName(…array))
扩展运算符的应用:
1.数组的合并 2.数组的克隆 3.将伪数组转成真正的数组
数组的扩展运算符可以将一个数组转为用逗号分隔的参数序列,且每次只能展开一层数组。
对象的扩展运算符(…)用于取出参数对象中的所有可遍历属性,拷贝到当前对象之中。
let bar = { a: 1, b: 2 }; let baz = { …bar }; // { a: 1, b: 2 }
如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性
如果将扩展运算符用于数组赋值,只能放在参数的最后一位,否则会报错。
_const _array1= [1,2,3]
_const _array2= [4,5,6]
console.log(…array1,…array2)数组的合并
_const _array3= […array1]
console.log(array3)//浅拷贝数组的克隆
_const _array= [‘qcq’,24,’宝鸡’]
_function _setName(){
console.log (…arguments)
}
setName (array)
扩展运算符的作用及使用场景
(1)对象扩展运算符
对象的扩展运算符(…)用于取出参数对象中的所有可遍历属性,拷贝到当前对象之中。
let bar = { a: 1, b: 2 }; let baz = { …bar }; // { a: 1, b: 2 } 复制代码
上述方法实际上等价于:
let bar = { a: 1, b: 2 }; let baz = Object.assign({}, bar); // { a: 1, b: 2 } 复制代码
Object.assign方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。Object.assign方法的第一个参数是目标对象,后面的参数都是源对象。(如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性)。
同样,如果用户自定义的属性,放在扩展运算符后面,则扩展运算符内部的同名属性会被覆盖掉。
let bar = {a: 1, b: 2}; let baz = {…bar, …{a:2, b: 4}}; // {a: 2, b: 4} 复制代码
利用上述特性就可以很方便的修改对象的部分属性。
在redux中的reducer函数规定必须是一个纯函数,reducer中的state对象要求不能直接修改,可以通过扩展运算符把修改路径的对象都复制一遍,然后产生一个新的对象返回。将原来的属性用扩展运算符展开,将要替换的属性放在其后面。this.setState({p:{…p,a:5}})修改p里面的a属性。
如果需要进行数组添加 需要用这种方式,不能用unshift 因为这种方式 用对象字面量的形式创建,不是原来的对象 ,利用数组的扩展字符串的合并
const {name} = this.state
this.setState({name:[‘xiaoLiu’,…this.state.name]})
需要注意:扩展运算符对对象实例的拷贝属于浅拷贝。
(2)数组扩展运算符
数组的扩展运算符可以将一个数组转为用逗号分隔的参数序列,且每次只能展开一层数组。
console.log(…[1, 2, 3]) // 1 2 3 console.log(…[1, [2, 3, 4], 5]) // 1 [2, 3, 4] 5 复制代码
下面是数组的扩展运算符的应用:
- 将数组转换为参数序列
function add(x, y) { return x + y; } const numbers = [1, 2]; add(…numbers) // 3 复制代码
- 复制数组
const arr1 = [1, 2]; const arr2 = […arr1]; 复制代码
要记住:扩展运算符(…)用于取出参数对象中的所有可遍历属性,拷贝到当前对象之中,这里参数对象是个数组,数组里面的所有对象都是基础数据类型,将所有基础数据类型重新拷贝到新的数组中。
- 合并数组
如果想在数组内合并数组,可以这样:
const arr1 = [‘two’, ‘three’];const arr2 = [‘one’, …arr1, ‘four’, ‘five’];// [“one”, “two”, “three”, “four”, “five”] 复制代码
- 扩展运算符与解构赋值结合起来,用于生成数组
const [first, …rest] = [1, 2, 3, 4, 5];first // 1rest // [2, 3, 4, 5] 复制代码
需要注意:如果将扩展运算符用于数组赋值,只能放在参数的最后一位,否则会报错。
const […rest, last] = [1, 2, 3, 4, 5]; // 报错const [first, …rest, last] = [1, 2, 3, 4, 5]; // 报错 复制代码
- 将字符串转为真正的数组
[…’hello’] // [ “h”, “e”, “l”, “l”, “o” ] 复制代码
- 任何 Iterator 接口的对象,都可以用扩展运算符转为真正的数组
比较常见的应用是可以将某些数据结构转为数组:
// arguments对象 function foo() { const args = […arguments]; } 复制代码
用于替换es5中的Array.prototype.slice.call(arguments)写法。
- 使用Math函数获取数组中特定的值
const numbers = [9, 4, 7, 1]; Math.min(…numbers); // 1 Math.max(…numbers); // 9
ES6-Symbol类型的理解:
Symbol 值通过Symbol函数生成。这就是说,对象的属性名现在可以有两种类型,
一种是原来就有的字符串,另一种就是新增的 Symbol 类型。
凡是属性名属于 Symbol 类型,就都是独一无二的,
可以保证不会与其他属性名产生冲突。
Symbol函数可以接受一个字符串作为参数,表示对 Symbol 实例的描述,主要是为了在控制台显示,或者转为字符串时,比较容易区分。


ES6-迭代器的理解:
遍历器(Iterator)就是一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。
任何数 据结构只要部署 Iterator 接口,就可以完成遍历操作;
ES6 创造了一种新的遍历命令 for…of 循环,Iterator 接口主要供 for…of 消费;
迭代器:按照我们的意愿去自定义遍历数据,所谓迭代器就是一个具有next()方法的对象,该结果对象有两个属性,value表示当前的值,done标识结果状态。而for of 是一个可以遍历迭代器对象的方式,然而还有一点就是数据只要具有Symbol.iterator属性,就可以认为是可以遍历的。但是数组对象是系统默认添加了Symbol.iterator属性,直接可以遍历成功。
for…in和for…of的区别
for…of 是ES6新增的遍历方式,允许遍历一个含有iterator接口的数据结构(数组、对象等)并且返回各项的值,和ES3中的for…in的区别如下
- for…of 遍历获取的是对象的键值,for…in 获取的是对象的键名;
- for… in 会遍历对象的整个原型链,性能非常差不推荐使用,而 for … of 只遍历当前对象不会遍历原型链;
- 对于数组的遍历,for…in 会返回数组中所有可枚举的属性(包括原型链上可枚举的属性),for…of 只返回数组的下标对应的属性值;
总结: for…in 循环主要是为了遍历对象而生,不适用于遍历数组;for…of 循环可以用来遍历数组、类数组对象,字符串、Set、Map 以及 Generator 对象。
原生具备 iterator 接口的数据(可用 for of 遍历):<br /> Array; <br /> Arguments; <br /> Set; <br /> Map; <br /> String; <br /> TypedArray; <br /> NodeList;<br /> 工作原理:<br /> 1. 创建一个指针对象,指向当前数据结构的起始位置; <br /> 2. 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员; <br /> 3. 接下来不断调用 next 方法,指针一直往后移动,直到指向后一个成员;<br /> 4. 每调用 next 方法返回一个包含 value 和 done 属性的对象;<br /> value:值 done:是否遍历完毕<br /> 注:需要自定义遍历数据的时候,要想到迭代器<br /> <script><br /> _const_array= ['1a','2b','3c','4d']<br /> for(_let_indexofarray){<br /> console.log(index)<br /> }<br /> //for in遍历对象时输出所有的属性名,遍历数组会输出数组元素的下标;for of遍历对象报错,遍历数组输出数组元素的值<br /> // 创建一个迭代器对象<br /> _const_index=array[Symbol.iterator]()<br /> console.log(index.next())<br /> console.log(index.next())<br /> console.log(index.next())<br /> console.log(index.next())<br /> console.log(index.next())
自创建迭代器接口:
//需求:用for of遍历 每次返回的结果是数组里面的成员(迭代器完成自定义对对象的遍历)
const person = {
name: [‘猪八戒’, ‘孙悟空’, ‘唐僧’, ‘沙和尚’],
age: 24,
//创建迭代器接口
Symbol.iterator {
let index = 0//设置遍历索引
let that = this//保存this
return {
next:function(){
if (index < that.name.length) {
index++
return {value: that.name[index],done: false}
}
else{
return {value:undefined,done:true}
}
}
}
}
}
for (let value of person) {
console.log(value)
}
ES6-Generator生成器:
函数是协程在 ES6 的实现,最大特点就是可以交出函数的执行权(即暂停执行)。
生成器函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同;
上面代码就是一个 Generator 函数。它不同于普通函数,是可以暂停执行的,所以函数名之前要加星号,以示区别。
整个 Generator 函数就是一个封装的异步任务,或者说是异步任务的容器。异步操作需要暂停的地方,都用 yield 语句注明。Generator 函数的执行方法如下。
var g = gen(1);
g.next() // { value: 3, done: false }
g.next() // { value: undefined, done: true }
上面代码中,调用 Generator 函数,会返回一个内部指针(即遍历器 )g 。
这是 Generator 函数不同于普通函数的另一个地方,即执行它不会返回结果,返回的是指针对象。
第二个next()括号里面的参数是第一个yield语句的返回值。
调用指针 g 的 next 方法,会移动内部指针(即执行异步任务的第一段),指向第一个遇到的 yield 语句,
上例是执行到 x + 2 为止。
换言之,next 方法的作用是分阶段执行 Generator 函数。
每次调用 next 方法,会返回一个对象,表示当前阶段的信息( value 属性和 done 属性)。
value 属性是 yield 语句后面表达式的值,表示当前阶段的值;done 属性是一个布尔值,
表示 Generator 函数是否执行完毕,即是否还有下一个阶段。
六、Generator 函数的数据交换和错误处理
Generator 函数可以暂停执行和恢复执行,这是它能封装异步任务的根本原因。除此之外,它还有两个特性,使它可以作为异步编程的完整解决方案:函数体内外的数据交换和错误处理机制。
next 方法返回值的 value 属性,是 Generator 函数向外输出数据;next 方法还可以接受参数,这是向 Generator 函数体内输入数据。
生成器其实就是一个特殊的函数
异步编程 纯回调函数 node fs ajax mongodb
yield:函数代码的分隔符
ES6-set和get:
与 ES5 一样,在“类”的内部可以使用get和set关键字,
对某个属性设置存值函数和取值函数,拦截该属性的访问行为。
