块级作用域和函数
es6明确规定,可以在块级作用域中声明,即使在严格模式下也不会报错
//首先在全局作用域中声明f函数
function f() {
console.log('I am outside!'); }
(function () {
if (false) {
// 重复声明一次函数f
//在es5中执行时,下面的函数定义会被提升到if外面,因为if不是块级作用域
//在es6执行时,if是块级作用域,里面声明的函数f对外面没有影响,if false 里面不会执行,变量也不会提升,
function f() {
console.log('I am inside!'); }
}
//es5最终输出inside
//es6最终输出outside,
f();
}());
块级作用域中声明函数,es6会默认当作let声明,但是一些浏览器会将es6块级函数声明当作var声明,会将声明提升到作用域最前面,但是函数体无法提升,所以可能会导致未定义
// ES6的浏览器环境
function f() {
console.log('I am outside!'); }
(function () {
var f = undefined;
if (false) {
function f() {
console.log('I am inside!'); }
}
f();
}());
// Uncaught TypeError: f is not a function
所以在块级作用域声明函数时,最好使用函数表达式,不会提升函数声明,在任何坏境下结果都是一样的
// 函数声明语句
{
let a = 'secret';
function f() {
return a;
}
}
// 函数表达式
{
let a = 'secret';
let f = function () {
return a;
};
}
const命令
const一旦声明就必须初始化,并且以后不可改变值
const声明对象,只能保证对象的地址不变,但是不能保证对象的值不变,
const foo = {
};
foo.prop = 123;
foo.prop
// 123
foo = {
}; // TypeError: "foo" is read-only
const a = [];
a.push('Hello'); // 可执行
a.length = 0; // 可执行
a = ['Dave']; // 报错
//彻底冻结对象,包括对象的属性
var constantize = (obj) => {
Object.freeze(obj);
//获取属性名,如果属性值是对象,就递归继续冻结该对象
Object.keys(obj).forEach( (key, value) => {
if ( typeof obj[key] === 'object' ) {
constantize( obj[key] );
}
});
};
es6声明变量的方法:var let const function class import
es6规定,var和function声明的全局变量是全局对象的属性,但是新增加的不是,全局对象,浏览器值window,node.js是global
解构赋值
将数组和对象解构,提取值,赋值给其他变量
以下是数组模式匹配赋值,只要模式相同就可以赋值
var [a, b, c] = [1, 2, 3];
//表示从数组中提取值,一一对应赋值给新的数组变量
//模式完全匹配赋值
let [foo, [[bar], baz]] = [1, [[2], 3]];
foo // 1
bar // 2
baz // 3
//省略前面参数赋值
let [ , , third] = ["foo", "bar", "baz"];
third // "baz"
//省略中间参数赋值
let [x, , y] = [1, 2, 3];
x // 1
y // 3
//省略末尾参数,使用点语法解构赋值
let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]
//点语法使用一个数组接收参数
let [x, y, ...z] = ['a'];
x // "a"
y // undefined
z // []
不完全结构
//多余的参数无法匹配,忽略掉
let [x, y] = [1, 2, 3];
x // 1
y // 2
let [a, [b], d] = [1, [2, 3], 4];
a // 1
b // 2
d // 4
不可遍历的对象无法解构
let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {
};
只要有iterator,就可以解构赋值
let [x, y, z] = new Set(["a", "b", "c"]);
x // "a"