es6小记
let, const, class, extends, super, arrow functions, template string, destructuring, default, rest arguments,import export, promise, generator(yield和next),Symbol,set,map
1.let const
let定义之后可以修改
cons就是常量,定义之后不能改变,只能在初始化赋值
let和const不能重新定义,都是块级作用域里有效
没有了var的变量提升(es5时,变量函数都可以先使用后声明)
还会导致暂时性死区:
var tmp=123; if(true){ tmp="abc"; let tmp; }
结果如下:
虽然上面的代码中存在全局变量tmp,但是块级作用域内let又声明了一个局部变量tmp,导致后者绑定了块级作用域,所以在let声明变量前,对tmp赋值会报错。此即暂时性死区。
2.class,extends,super
class javascript出现了常规编程语言都有的类
extends 是类的继承
super 是继承后必须在constructor调用的继承类的构造函数
3.arrow function
就是() => {}
不同于function xxx(){}的是:
1)this的定义取决于箭头函数在哪儿定义,而非箭头函数执行的上下文环境(function的this定义就是取决于执行时候的上下文,例如student.say()函数里面的this就是student对象,如果直接say(),this就是window)
2)不能再用arguments,取而代之的是rest(后面介绍)
3)不能用new把函数实体话
4)call/apply/bind方法仍适用于箭头函数,但就算调用这些方法扩充当前作用域,this也依旧不会变化
4.template string
就是反引号(`)的引入,可以在两个反引号之间写多行,而且可以用${xxx}在字符串引入变量,效果如下:
5.destructuring 声明解构
ps:解构的时候必须要同时声明,两者不能分开
对象解构:
数组解构:
复杂解构:
当然可以改变解构粒度:
6.default(默认参数), rest(剩余参数)
default:可以定义默认值
rest:取代arguments,在形参前面加(...)
...不充当剩余参数时,还可以做展开功能
或者展开对象
{...{a:123,b:456},c:999} //{a: 123, b: 456, c: 999}
7.import export
在es6提出import前,js的模块引入是由require()实现的,但是这个并不是es5原生的方法,而是第三方的支持(CommonJS(服务器端)和AMD(浏览器端,如require.js))
requirejs写法:
//content.js define('content.js', function(){ return 'A cat'; }) //index.js require(['./content.js'], function(animal){ console.log(animal); //A cat })
commonJS写法:
//content.js module.exports = 'A cat' //index.js var animal = require('./content.js')
ES6写法:
//content.js export default 'A cat' //index.js import animal from './content'
高级用法:
如果一个文件多次export,那么只能有一个default
export default 'A cat' export function say(){ return 'Hello!' } export const type = 'dog'
那么引入文件要这样写:
默认的写在大括号外,其他写在里面,我们还可以通过as改名
import animal, { say, type as typex } from './content' let says = say() console.log(`The ${typex} says ${says} to ${animal}`)
8.promise
直接看代码:
function helloWorld (ready) { return new Promise(function (resolve, reject) { if (ready) { resolve("Hello World!"); } else { reject("Good bye!"); } }); } helloWorld(true).then(function (message) { alert(message); }, function (error) { alert(error); });
常用于指定异步请求后,接下来执行操作(成功和失败分别执行什么方法),Promise没有then也会执行(这容易造成错误,因为没有then提供成功失败要执行的函数),这区别于RXJS里面Observable(有地方用到才执行,被subscribe才会执行),promise有3种状态:pending(待定)、resolved(已完成)、rejected(拒绝)
9.generator (yield和next)
看下面的例子:
function* gen( var y = yield x + 2; return y; } var g = gen(1); g.next() // { value: 3, done: false } g.next(2) // { value: 2, done: true }
第一个 next 方法的 value 属性,返回表达式 x + 2 的值(3)。
第二个 next 方法带有参数2,这个参数可以传入 Generator 函数,作为上个阶段异步任务的返回结果,被函数体内的变量 y 接收。因此,这一步的 value 属性,返回的就是2(变量 y 的值)。
PS:1.done表示该generator函数是否执行完。
2.每次next都会返回yield或者return后面的值
3.给next()传的值是传给yield赋值的变量如上面的y
10.Symbol
这个是新的原始数据类型typeof Symbol() == 'symbol',用于产生一个独一无二的值
Symbol('foo') == Symbol('foo') //false
如果想相等,用Symbol.for,在全局注册一个Symbol
Symbol.for('abc') == Symbol.for('abc') //true
获取Symbol注册表上某个值用Symbol.keyFor()
let a = Symbol.for('amie') Symbol.keyFor(a) // amie
Symbol 键的属性不会在对象的 JSON 中显示,也不会在 for-in 循环和Object.keys
中被枚举出来
myObject = { a: 123, [Symbol('abc')]: 456 } JSON.stringify( myObject ) //"{"a":123}" for( var prop in myObject ) { console.log( prop, myObject[prop] ); } //a 123 console.log( Object.keys( myObject ) ); // ["a"]
要获取Symbol作为键的值应该这样写:
myObject[Object.getOwnPropertySymbols(myObject)[0]] // 456
Symbol主要是用于作为对象的私有属性,这比‘_’的方式更加容易与公有属性区分开
11.SET
set是es6新增的数据结构,是一种类数组常用书数组去重
Array.from(new Set(myArray))
常用的方法有add,delete,has,clear
12.MAP
map是es6新增的数据结构,可以理解成比Object更强大的一个散列表
Object的键是不能是引用类型的(会强制被转化为'[object Object]'),但是map却可以
let m = new Map() let a = {a:123} m.set(a,999) m.get(a) //999
常用方法有has delete
总结
1.变量
var 重复声明、函数级
let 不能重复声明、块级、变量
const 不能重复声明、块级、常量
2.箭头函数
a.方便
i.如果只有一个参数,()可以省
ii.如果只有一个return,{}也可以省
b.修正this
this相对正常点
3.参数扩展
收集
扩展
默认参数
function show(a, b=5){
}
4.数组方法
map 映射
reduce 汇总:一堆->一个
filter 过滤:一堆->剩下的
forEach 循环
5.字符串
startsWith/endsWith
字符串模板:`${a}xxx${b}`
6.Promise
封装异步操作
Promise.all([]);
7.generator
function *show(){
yield
}
8.JSON
JSON.stringify({a:12,b:5}) => '{"a":12,"b":5}'
JSON.parse('{"a":12,"b":5}')=> {a:12,b:5}
9.解构赋值
let [a,b,c]=[12,5,8];
左右结构一样
右边是个合法的东西
声明、赋值一次完成
10.面向对象
class Test{
constructor(){
this.xxx=
}
方法1(){
}
方法2(){
}
}
class Cls2 extends Cls1{
constructor(){
super();
}
}