ES6语法规范学习
let、const、var 三者比较
-
不存在变量提升
let、const 声明变量之前无法使用
var 则会存在变量提升,没声明就可以使用
-
暂时性死区
- 在块级作用域内,使用let声明的变量不受块级外的全局变量等的影响。
-
不允许重复声明
- let在相同作用域内不允许重复声明
-
const声明常量,声明的常量不允许改变
- 注意一点,const指向的是变量所在地址,对于变量中的数据结构则不能控制了
例如,声明一个数组,可以向数组内增加数据,但是无法对数组内的值更改。
变量的赋值
- 相比较以前而言可以进行匹配赋值。
let [a, b, c] = [1, 2, 3];
- 只要某种数据结构具有 Iterator 接口,都可以采用数组形式的解构赋值。
赋值案例
function* fibs() {
let a = 0;
let b = 1;
while (true) {
yield a;
[a, b] = [b, a + b];
}
}
let [first, second, third, fourth, fifth, sixth] = fibs();
sixth // 5
- 解构赋值允许指定默认值。
let [foo = true] = [];
* 默认值还可以变量,前提是这个变量已经声明
- 对象赋值
let { foo: foo1, bar: bar1 } = { foo: 'aaa', bar: 'bbb' };
* 变量名的被赋值的是后者,例如foo:foo1,被赋值的是foo1,而不是foo。foo是匹配等号右边属性名为foo的,将其赋值给foo1
- 对嵌套对象进行赋值
const node = {
loc: {
start: {
line: 1,
column: 5
}
}
};
let { loc, loc: { start }, loc: { start: { line }} } = node;
console.log(loc);
console.log(start);
console.log(line);
输出结果:
{ start: { line: 1, column: 5 } }
{ line: 1, column: 5 }
1
-
解构赋值常用用途
交换值
函数可以有多个返回值
设定函数参数默认值
解析JSON对象中数据
…………
函数
可以设定默认参数了。
-
使用参数默认值时,函数不能有同名参数。
- 函数同名时 后面的函数会覆盖前面的函数
函数参数值可以设定为undefined 表示此参数可以省略
-
rest参数
- 写法 (rest参数后不能再有其他参数)
function 函数名(...变量名)
实例
funciton rest(...arr){}
- 函数的length属性,不包含rest参数
name属性 调用name属性返回函数名
ES6中匿名函数会返回实际函数名,在ES5中是空串
-
箭头函数
ES6中新的函数定义 可以使用
=>
定义函数函数体内只有返回语句或单条语句,则可以省略
{}
,注意单条语句若不想要返回值 在=>
后加void
例如,
var canntReturn=cannt=>void 1
- 函数只有单个参数可以省略
()
例如:
var first=first=>1
- 函数的只有一个返回语句,返回值是对象时,要注意加上
()
例如,
var obj=()=>({name:"obj"});
-
注意事项
this指向的问题,this指向的是函数生效时所在的对象
不可使用new命令,不能当作构造函数
无法使用arguments对象,不过可用rest替代
不能用作Generator函数
//第一点的案例 function foo() setTimeout(() => { console.log('id:', this.id); }, 100);} var id = 21; foo.call({ id: 42 }); //对于这里的call函数作用,原理等在下一个日报将进行分析。
-
不适用场景
对象内的方法定义
需要动态this的时候,像点击事件操作dom对象时,这里this指的就是这个dom
需要大量读写,函数体复杂时,使用普通函数
-
尾调用优化
尾调用优化指不需要保存外层函数调用帧,直接用内存调用帧取代外层调用帧
尾调用优化是为了节省内存
尾递归 就非常适合采用尾递归优化,这样 不会导致栈溢出
尾调用优化,仅在严格模式下开启。
在非严格模式下,我们可以将尾调用递归改写成循环,从而实现尾调用优化。
Set
Set本身是一个构造函数,用来生成 Set 数据结构。
可利用Set去重复 利用rest和解构赋值
let arr=[1,1,2,2,3];
let arr1=[...new Set(arr)];
Set 插入和遍历顺序一致。
-
Set遍历方法
Set.prototype.keys():返回键名的遍历器
Set.prototype.values():返回键值的遍历器
Set.prototype.entries():返回键值对的遍历器
Set.prototype.forEach():使用回调函数遍历每个成员
Set实现交并差的实例
let a = new Set([1, 2, 3]); let b = new Set([4, 3, 2]); // 并集 let union = new Set([...a, ...b]); // Set {1, 2, 3, 4} // 交集 let intersect = new Set([...a].filter(x => b.has(x))); // set {2, 3} // 差集 let difference = new Set([...a].filter(x => !b.has(x))); // Set {1}
pomise 对象
用于异步操作
从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。
-
Promise的两个特点
-
自身状态不受外界影响。只有异步操作结果能改变 这三种状态如下:
pending(进行中)
fulfilled(已成功)
rejected(已失败)
-
2. 状态改变后,不会变,任何时候都可以去获取结果。例如,事件不监听,但在结果产生后再设置监听,无法再获取结果,而对于Promise不影响。
- 基本用法及实例解析
var promise = new Promise(function (resolve, reject) {
if (/* 异步操作成功 */) {
resolve(data);
} else {
/* 异步操作失败 */
reject(error);
}
});
上面参数作用
resolve函数的作用:在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
reject函数的作用:在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
在Promise生成后,用 then 方法分别指定 resolved 状态和 reject 状态的回调函数
promise.then(function(data) {
// do something when success
}, function(error) {
// do something when failure
});
第二个 function(error) 不是必选项,可以省略
这是reject函数 回调的。
一个具体的实例
var promise = new Promise(function(resolve, reject) {
console.log('before resolved');
resolve();
console.log('after resolved');
});
promise.then(function() {
console.log('resolved');
});
console.log('outer');
输出结果为
before resolved
after resolved
outer
resolved
解释:resolve的回调只有在同步操作全部完成后才能执行
异步图片加载实例
//url 传入的相对地址 这个方法是返回一个Promise对象实例。
function loadImageAsync(url) {
return new Promise(function(resolve, reject) {
//html中的Image对象,在NODEJS环境下
//Image未定义
const image = new Image();
//onload 当图像装载完毕时调用的事件句柄。
image.onload = function() {
//当图片加载成功后调用resolve
resolve(image);
};
//onerror 在装载图像的过程中发生错误时调用的事件句柄。
image.onerror = function() {
//当图片加载错误后调用reject
reject(new Error('Could not load image at ' + url));
};
//设置图像的 URL
image.src = url;
});
}
注意事项:
-
then的使用.
then方法返回的是一个新的Promise实例,不再是原来的最初的Promise实例。因此可以采用链式写法,即then方法后面再调用另一个then方法。
实例
var p=new Promise(function(resolve,reject){ console.log('创建一个Promise实例'); resolve(1); }); var p2=new Promise(function(resolve,reject){ console.log('创建一个Promise实例'); resolve(1); }); //非链式then p.then(function(data){ console.log("开始非链式结构的then:") return ++data; }); p.then(function(data){ return ++data; }); p.then(function(data){ console.log("data:"+data); }); //链式then p2.then(function(data){ console.log("开始链式结构的then:") return ++data; }) .then(function(data){ return ++data; }) .then(function(data){ console.log("data:"+data); });
输出结果: 创建一个Promise实例 创建一个Promise实例 开始非链式结构的then: data:1 开始链式结构的then: data:3
模板字符串$ 可以在字符串中嵌入变量
- 例如,
let obj='.js';
let str='index$('obj')';
Module 大致了解
import 输入其他模块提供的功能
export 规定模块的对外接口
装饰器
相当于切面编程中的切点。
不对函数使用
在ES7中