与var不一样,新的变量声明方式带来了一些不同的特性,其中最重要的两个特性就是提供了块级做用域与再也不具有变量提高:html
{ let a = 10; var b = 1; } a // ReferenceError: a is not defined. b // 1
上面代码在代码块之中,分别用let
和var
声明了两个变量。而后在代码块以外调用这两个变量,结果let
声明的变量报错,var
声明的变量返回了正确的值。这代表,let
声明的变量只在它所在的代码块有效。json
var
命令会发生“变量提高”现象,即变量能够在声明以前使用,值为undefined
。这种现象多多少少是有些奇怪的,按照通常的逻辑,变量应该在声明语句以后才可使用。数组
为了纠正这种现象,let
命令改变了语法行为,它所声明的变量必定要在声明后使用,不然报错。函数
// var 的状况 console.log(foo); // 输出undefined var foo = 2; // let 的状况 console.log(bar); // 报错ReferenceError let bar = 2;
上面代码中,变量foo
用var
命令声明,会发生变量提高,即脚本开始运行时,变量foo
已经存在了,可是没有值,因此会输出undefined
。变量bar
用let
命令声明,不会发生变量提高。this
这表示在声明它以前,变量bar
是不存在的,这时若是用到它,就会抛出一个错误。spa
let
不容许在相同做用域内,重复声明同一个变量。指针
// 报错 function func() { let a = 10; var a = 1; } // 报错 function func() { let a = 10; let a = 1; }
所以,不能在函数内部从新声明参数。code
function func(arg) { let arg; } func() // 报错 function func(arg) { { let arg; } } func() // 不报错
一样在块级做用域有效的另外一个变量声明方式是 const
,const
声明一个只读的常量。一旦声明,常量的值就不能改变。htm
ES6 中,const
声明的常量相似于指针,它指向某个引用,也就是说这个「常量」并不是一成不变的,如:对象
{ const ARR = [5,6]; ARR.push(7); console.log(ARR); // [5,6,7] ARR = 10; // TypeError }
有几个点须要注意:
let
关键词声明的变量不具有变量提高(hoisting)特性let
和 const
声明只在最靠近的一个块中(花括号内)有效const
声明时,请使用大写变量,如:CAPITAL_CASINGconst
在声明时必须被赋值ES6 中,箭头函数就是函数的一种简写形式,使用括号包裹参数,跟随一个 =>
,紧接着是函数体:
原
var fun = function(){ console.log('hello') } fun();
简
var fun = () => { console.log('hello') } fun()
注意的地方
1.不能用this,箭头函数中的this指向window
2.不能使用arguments
例子(this):html内容
<style> #box{ width: 100px; height: 100px; border: 1px solid #000; } </style> </head> <body> <div id="box"></div>
JS内容
原:
var box = document.getElementById("box"); box.onclick = function fun(){ this.style.background = '#f00'; }
效果点击boxDIV后会变红色
箭头:
var box = document.getElementById("box"); box.onclick = () => { this.style.background = '#f00'; }
例子(arguments)
原
function fun(){ console.log(arguments); } fun(1,2,3,4)
效果:
箭头:
var fun = () => { console.log(arguments); } fun(1,2,3,4)
ES6 容许按照必定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构
之前,为变量赋值,只能直接指定值。
let a = 1; let b = 2; let c = 3;
ES6 容许写成下面这样。
let [a, b, c] = [1, 2, 3];
(1)本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。下面是一些使用嵌套数组进行解构的例子。
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 // []
(2)若是解构不成功,变量的值就等于undefined
。
let [foo] = []; let [bar, foo] = [1];
以上两种状况都属于解构不成功,foo
的值都会等于undefined
。
(3)另外一种状况是不彻底解构,即等号左边的模式,只匹配一部分的等号右边的数组。这种状况下,解构依然能够成功。
let [x, y] = [1, 2, 3]; x // 1 y // 2 let [a, [b], d] = [1, [2, 3], 4]; a // 1 b // 2 d // 4
上面两个例子,都属于不彻底解构,可是能够成功。
(4)json格式
对象的解构赋值
var {a,b,c} = {a:10,c:30,b:20}; //能够调换顺序 console.log(a,b,c); var [a,[b,c],d] = [5,[10,20],30]; //格式对应便可 console.log(a,b,c,d)
与数组同样,解构也能够用于嵌套结构的对象。
let obj = { p: [ 'Hello', { y: 'World' } ] }; let { p: [x, { y }] } = obj; x // "Hello" y // "World"
解构赋值容许指定默认值
let [foo = true] = []; foo // true let [x, y = 'b'] = ['a']; // x='a', y='b' let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'
注意,ES6 内部使用严格相等运算符(===
),判断一个位置是否有值。因此,只有当一个数组成员严格等于undefined
,默认值才会生效。
for...of
VS for...in
) for...of
用于遍历一个迭代器,如数组:
var arr = ["red","green","blue","yellow","black"]; for(var i of arr){ console.log(i); //输出的直接是值 }
for...in
用来遍历对象中的属性:
var arr = ["red","green","blue","yellow","black"]; for(var i in arr){ console.log(i); //输出的是索引 console.log(arr[i]); }