简介
ECMAScript和JavaScript的关系
let和const
- 变量提升
// var 的情况
console.log(foo); // 输出undefined
var foo = 2;
- 变量覆盖
var tmp = new Date();
function f() {
console.log(tmp);
if (false) { var tmp = "hello world";
} }
f(); // undefined
- 变量泄露
var s = 'hello';
for (var i = 0; i < s.length; i++) {
console.log(s[i]);
}
console.log(i); // 5
~~
为了解决上面两个问题,ES6引入了let和const。
这两个都是块级作用域。不同的是const定义的变量初始化之后就不能变化了。
什么是块级作用域呢?类似于 if、switch 条件选择或者 for、while 这样的循环体即是所谓的块级作用域,或者更简单一点使用大括号括起来的就叫做块级作用域。
块级作用域的最大好处就是不会产生作用域提升,如下所示:
~~~js
{
let a = 10;
var b = 1;
}
a // ReferenceError: a is not defined.
b // 1
解构赋值
let [a,b,c] = [1,2,3];
let [,third] = ["foo","bar","baz"];
let [x,y] = [1,3];
let [head,...tail] = [1,3,4];
let [x,3];
let [foo = true] = [];
foo // true
let [x,y = 'b'] = ['a'];
// x='a',y='b'
let [x,y = 'b'] = ['a',undefined];
// x='a',y='b’
let [x = 1] = [undefined];
x // 1
let [x = 1] = [null];
x // null
function f() {
console.log('aaa');
}
let [x = f()] = [1];
let { bar,foo } = { foo: "aaa",bar: "bbb" };
foo // "aaa"
bar // "bbb"
let { baz } = { foo: "aaa",bar: "bbb" };
baz // undefined
var { foo: baz } = { foo: 'aaa',bar: 'bbb' };
baz // "aaa"
let obj = { first: 'hello',last: 'world' };
let { first: f,last: l } = obj;
f // 'hello'
l // 'world'
let obj = { p: [ 'Hello',{ y: 'World' } ] };
let { p: [x,{ y }] } = obj;
x // "Hello"
y // "World"
let x = 1;
let y = 2;
[x,y] = [y,x];
// 返回一个数组
function example() { return [1,3]; }
let [a,c] = example();
// 返回一个对象
function example() { return { foo: 1,bar: 2 }; }
let { foo,bar } = example();
//提取JSON数据
let jsonData = { id: 42,status: "OK",data: [867,5309] };
let { id,status,data: number } = jsonData;
数组的扩展
- 类似数组的对象(array-like object)
- 可遍历(iterable)的对象(包括ES6新增的数据结构Set和Map)。
let arrayLike = { '0': 'a','1': 'b','2': 'c',length: 3 };
// ES5的写法
var arr1 = [].slice.call(arrayLike);
// ['a','b','c']
// ES6的写法 let arr2 = Array.from(arrayLike);
// ['a','c']
// NodeList对象
let ps = document.querySelectorAll('p');
Array.from(ps).forEach(function (p) { console.log(p); });
// arguments对象
function foo() { var args = Array.from(arguments);
// ...
}
Array.from('hello') // ['h','e','l','o']
let namesSet = new Set(['a','b'])
Array.from(namesSet) // ['a','b']
function foo() { var args = [...arguments]; } // arguments对象
[...document.querySelectorAll('div')] // NodeList对象
Array.from(arrayLike,x => x * x);
// 等同于
Array.from(arrayLike).map(x => x * x);
Array.from([1,3],(x) => x * x)
// [1,4,9]
Array.of(3,11,8) // [3,8]
Array.of(3) // [3]
Array.of(3).length // 1
Array() // []
Array(3) // [,]
Array(3,8]
函数的扩展
function log(x,y = 'World') { console.log(x,y); }
function Point(x = 0,y = 0) { this.x = x; this.y = y; }
function foo({x,y = 5}) { console.log(x,y); }
foo({}) // undefined,5
foo({x: 1}) // 1,5
foo({x: 1,y: 2}) // 1,2
foo() // TypeError: Cannot read property 'x' of undefined
// 写法一
function m1({x = 0,y = 0} = {})
{ return [x,y]; }
// 写法二
function m2({x,y} = { x: 0,y: 0 })
{ return [x,y]; }
m1() // [0,0]
m2() // [0,0]
m1({x: 3,y: 8}) // [3,8]
m2({x: 3,8]
m1({x: 3}) // [3,0]
m2({x: 3}) // [3,undefined]
m1({}) // [0,0];
m2({}) // [undefined,undefined]
m1({z: 3}) // [0,0]
m2({z: 3}) // [undefined,undefined]