与var不同,新的变量声明方式带来了一些不一样的特性,其中最重要的两个特性就是提供了块级作用域与不再具备变量提升:
{ let a = 10; var b = 1; } a // ReferenceError: a is not defined. b // 1
上面代码在代码块之中,分别用let
和var
声明了两个变量。然后在代码块之外调用这两个变量,结果let
声明的变量报错,var
声明的变量返回了正确的值。这表明,let
声明的变量只在它所在的代码块有效。
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
命令声明,不会发生变量提升。
这表示在声明它之前,变量bar
是不存在的,这时如果用到它,就会抛出一个错误。
let
不允许在相同作用域内,重复声明同一个变量。
// 报错 function func() { let a = 10; var a = 1; } // 报错 function func() { let a = 10; let a = 1; }
因此,不能在函数内部重新声明参数。
function func(arg) { let arg; } func() // 报错 function func(arg) { { let arg; } } func() // 不报错
同样在块级作用域有效的另一个变量声明方式是 const
,const
声明一个只读的常量。一旦声明,常量的值就不能改变。
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]); }
原文:https://www.cnblogs.com/gyix/p/10478133.html