块级作用域:在ES5中只有全局作用域与函数作用域,ES6中新增的块级作用域避免变量的覆盖与泄露。考虑到代码运行环境,在块级作用域中应避免声明函数,最好用函数表达式的方式声明。
let与const:let命令声明在作用域内有效的变量,必须严格的先声明,不能变量提升。const命令声明一个只读的常量,一旦声明则不能改变。两者在相同作用域中不能重复声明。在ES5中var声明的是一个全局的变量,并且可以变量提升。
顶层对象:在浏览器环境是指window对象。在node环境中指global对象。ES5中两者完全相等。这会导致在编译的时候不能报出变量未声明的错误,只有在运行阶段才会报错;在代码编写过程中很容易在不知不觉中创造出全局变量;顶层对象到处可以进行读写的,不利于模块化编程。另一方面。window对象有实体含义,指的是浏览器窗口对象,顶层对象是一个含有实际意义的对象也不合适。ES6为了改变这一点,一方面规定,为了保持兼容性,var
命令和function
命令声明的全局变量,依旧是顶层对象的属性;另一方面规定,let
命令、const
命令、class
命令声明的全局变量,不属于顶层对象的属性。也就是说,从ES6开始,全局变量将逐步与顶层对象的属性脱钩。
global对象:浏览器里顶层对象是window,但是node与web worker没有window对象;浏览器和web worker中self指向顶层对象,但是node里面没有self;在node中顶层对象是global,其他的环境都不支持。
兼容顶层对象的方法:
// 方法一
(typeof window !== 'undefined'
? window
: (typeof process === 'object' &&
typeof require === 'function' &&
typeof global === 'object')
? global
: this);
// 方法二
var getGlobal = function () {
if (typeof self !== 'undefined') { return self; }
if (typeof window !== 'undefined') { return window; }
if (typeof global !== 'undefined') { return global; }
throw new Error('unable to locate global object');
};
变量的解构赋值:ES6允许按照一定的模式,在数组与对象中提取值,对变量赋值,这被称作变量的解构赋值。
之前变量声明的方式var a = 1,b = 2,c = 3;
ES6允许 let [a,b,c] = [1,2,3] //a=1;b=2;c=3
let [first, ...other] = [1,2,3,4] //first=1;other = [2,3,4]
let [x,y] = [1,2,3,4] //x=1;y=2 这种方式是不完全解构,但是可以成功
本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。如果解构不成功,变量的值就等于undefined
;对于Set结构,也可以使用数组的解构赋值;解构赋值允许指定默认值。
解构不仅可以解构数组,还可以解构对象:let {name:aa} = {name:rancheer,age:23} //aa = rancheer
对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
如果变量名与属性名不一致:
let obj = {first:rancheer,second:allen}
let {first:f,second:s} = obj
f //rancheer
s//allen
对象嵌套解构:
let obj = {
p:[
'hello',
{w: 'world'}
]
}
let {p:[h, {w}]} = obj
h //hello
w//world
对一个已经声明的变量解构要注意在解构赋值语句外面添加()避免被JavaScript引擎认为是代码块
let x;
({x} = {x:1})
字符串的解构赋值:把字符串转化成一个类数组的方式进行解构
const [a,b,c,d,e] = 'hello'
a//h
b//e
c//l
d//l
e//o
类似数组的对象都有一个length
属性,因此还可以对这个属性解构赋值。let {length:len} = 'hello' //len = 5
函数参数的解构赋值:
function add([a, b]){
return a+b
}
add([2,3]) //5
let obj = [[1,2],[3,4]]
obj.map(([a,b])=>a+b); //[3,7]
undefined会触发属性的默认值 [1,undefined,3].map((x = 'yes')=>x) //[1,yes,3]
变量的解构赋值用途:
交换变量:let obj = [x,y]; [y,x] = obj
[x,y] = [y,x]
可以从函数中返回多个值:数组与对象
数组:
function getData(){
return [1,2,3];
}
var [a,b,c] = getData();
对象:
function getData(){
return {
name:rancheer,
age:23
}
}
var {name,age} = getData();
提取json数据:
var jsonData = {
name:rancheer,
age:23,
data:[a,b,c,d,e]
}
let {name,age,data:datas} = jsonData;
console.log(name,age,datas) //rancheer,23,[a,b,c,d,e]
函数参数的默认值:
jQuery.ajax = function(url,{async = false,cache = false,},{...})
变量map解构:
var map = new Map();
map.set('name','rancheer');
map.set('age',23);
for(let [key,value] of map){console.log('key: '+ key +' value: '+ value)}
//key:name value:rancheer;
//key:age value:23;