@phone
2017-11-22T08:06:37.000000Z
字数 3599
阅读 548
摘记
一:ES6 新增了let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。
二:ES6明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。
2.块级作用域
没有块级作用域会因为变量提升导致:
var tmp = new Date();
function f() {
console.log(tmp);
if (false) {
var tmp = 'hello world';
}
}
f(); // undefined
执行顺序:
var tmp;
var f;
tmp = new Date();
f = function(){}
var tmp;
console.log(tmp)
let实际上为 JavaScript 新增了块级作用域。
另外,还有一个需要注意的地方。ES6 的块级作用域允许声明函数的规则,只在使用大括号的情况下成立,如果没有使用大括号,就会报错。
3.const
const声明一个只读的常量。一旦声明,常量的值就不能改变。
对于const来说,只声明不赋值就会报错
const的作用域与let命令相同:只在声明所在的块级作用域内有效。
和let一样不提升
this指向的固定化,并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,导致内部的this就是外层代码块的this。正是因为它没有this,所以也就不能用作构造函数。
一.拓展运算符,在数组前面加上3个点,可以把数组变为逗号分隔的参数序列
console.log(...[1,2,3])//1 2 3
可是使用这个拓展运算符代替ES5中,需要使用apply来讲数组作为函数的参数
// ES5 的写法
function f(x, y, z) {
// ...
}
var args = [0, 1, 2];
f.apply(null, args);
// ES6的写法
function f(x, y, z) {
// ...
}
let args = [0, 1, 2];
f(...args);
应用:
1.复制数组
const a1 = [1, 2];
// 写法一
const a2 = [...a1];
// 写法二
const [...a2] = a1;
2.合并数组
// ES5的合并数组
arr1.concat(arr2, arr3);
// [ 'a', 'b', 'c', 'd', 'e' ]
// ES6的合并数组
[...arr1, ...arr2, ...arr3]
// [ 'a', 'b', 'c', 'd', 'e' ]
3.够正确识别四个字节的 Unicode 字符
'x\uD83D\uDE80y'.length // 4
[...'x\uD83D\uDE80y'].length // 3
4.Iterator接口的对象
任何 Iterator 接口的对象,都可以用扩展运算符转为真正的数组。
let nodeList = document.querySelectorAll('div');
let array = [...nodeList];
上面代码中,querySelectorAll方法返回的是一个nodeList对象。它不是数组,而是一个类似数组的对象。这时,扩展运算符可以将其转为真正的数组,原因就在于NodeList对象实现了 Iterator 。
对于那些没有部署 Iterator 接口的类似数组的对象,扩展运算符就无法将其转为真正的数组。
5.Map 和 Set 结构,Generator 函数
二.Array.from()
Array.from方法用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象(包括 ES6 新增的数据结构 Set 和 Map)。
二.Array.of()
Array.of方法用于将一组值,转换为数组。主要是弥补Array的不足
Array() // []
Array(3) // [, , ,]
Array(3, 11, 8) // [3, 11, 8]
Array.of() // []
Array.of(undefined) // [undefined]
Array.of(1) // [1]
Array.of(1, 2) // [1, 2]
三.数组实例的 find() 和 findIndex()
数组实例的find方法,用于找出第一个符合条件的数组成员。它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,然后返回该成员。如果没有符合条件的成员,则返回undefined。
[1, 5, 10, 15].find(function(value, index, arr) {
return value > 9;
}) // 10
和indexOf方法类似,但是indexOf返回的是出现的位置,而且如果没有找到会返回-1。find返回的是该成员
四.数组示例的fill方法
fill方法使用给定值,填充一个数组。
['a', 'b', 'c'].fill(7)
// [7, 7, 7]
new Array(3).fill(7)
// [7, 7, 7]
五.数组新增的三个方法
数组实例的 entries(),keys() 和 values()
entries()是对键值对进行遍历,相对的keys就是对键进行遍历,values就是对值进行遍历
他们返回的都是一个遍历器对象,可以用for...of循环进行遍历,
for (let index of ['a', 'b'].keys()) {
console.log(index);
}
// 0
// 1
for (let elem of ['a', 'b'].values()) {
console.log(elem);
}
// 'a'
// 'b'
for (let [index, elem] of ['a', 'b'].entries()) {
console.log(index, elem);
}
使用for...of遍历
六.数组实例的 includes()
Array.prototype.includes方法返回一个布尔值,表示某个数组是否包含给定的值,与字符串的includes方法类似。ES2016 引入了该方法。
与find和indexOf类似,但是又有不同,返回的是布尔值
七.数组的空位
空位是指数组中的这个位置没有任何值,如
Array(3)//[ , , ,]
这和undefined不一样,如果位置上是undefined,其实是有值的。
使用delete数组之后就是这个情况
ES5的方法再处理数组元素时,大多数都会跳过空位不处理。
ES6的方法则是会把空位置为undefined,并不会跳过
无论如何,都应该避免出现空位
一。简洁表达式
按照我的习惯,就是使用对象字面量来设置一个对象,但是简洁表达式可以用变量来设置。
变量名就是键名
let c = 1;
let b = 2;
let e = {c,d}
//也可以直接
let f ={method(){
console.log("111");
}}//方法名就是键
二。属性名表达式
ES6允许在设置对象属性的时候,使用表达式
let lastWord = 'last word';
const a = {
'first word': 'hello',
[lastWord]: 'world'
};
a['first word'] // "hello"
a[lastWord] // "world"
a['last word'] // "world"
属性名表达式不能和简洁表示法一起使用
3.Object.is()
判断两者的值是否相等,注意,是判断两者的值,而不是二者是否显相等。
Object.is() 判断两个值是否相同。如果下列任何一项成立,则两个值相同:
两个值都是 undefined 两个值都是 null 两个值都是 true 或者都是 false
两个值是由相同个数的字符按照相同的顺序组成的字符串 两个值指向同一个对象 两个值都是数字并且 都是正零 +0 都是负零 -0 都是 NaN
都是除零和 NaN 外的其它同一个数字 这种相等性判断逻辑和传统的 == 运算符所用的不同,==
运算符会对它两边的操作数做隐式类型转换(如果它们类型不同),然后才进行相等性比较,(所以才会有类似 "" == false 为 true
的现象),但 Object.is 不会做这种类型转换。这与===运算符也不一样。===运算符(和==运算符)将数字值-0和+0视为相等,并认为Number.NaN不等于NaN。
Object.is('foo', 'foo'); // true
Object.is(window, window); // true
Object.is('foo', 'bar'); // false
Object.is([], []); // false
var test = { a: 1 };
Object.is(test, test); // true
Object.is(null, null); // true
// 特例
Object.is(0, -0); // false
Object.is(-0, -0); // true
Object.is(NaN, 0/0); // true