我是看了http://wiki.jikexueyuan.com/project/es6/ 写的笔记,中间加了一些自己的理解。
let命令
let声明变量,用法类似var。
但是所有声明的变量只在let命令所在的代码块内有效。
{
let a = 1;
var b = 2;
}
a //ReferenceError: a is not defined 语法错误 a 没有定义
b //2
不存在变量提升
function func(){
console.log(bar);
console.log(foo);
let foo = 1;
var bar = 2;
}
func();
//undefined
//ReferenceError not defined
因var 存在变量提升,会上升到作用域的顶部,所以在console.log(bar)时 已经声明了,但是没有赋值,所以是undefined 而let不存在变量提升,所以console.log(foo)时 foo就不存在,所以ReferenceError
变量提升
function fuc(){
console.log(a)
var a = 1;
}
var 存在变量提升,所以实际代码运行时这样
function fuc(){
var a;
console.log(a);
a = 1;
}
这就是为什么不报错,而是现实a是undefined了
if (true) {
// TDZ开始
tmp = 'abc'; // ReferenceError
console.log(tmp); // ReferenceError
let tmp; // TDZ结束
console.log(tmp); // undefined
tmp = 123;
console.log(tmp); // 123
}
TDZ暂时性死区,实在声明之前就用了变量。
在let const声明变量之前,这些变量都不可以用,都会报错
函数作用域的影响
function bar(x=y , y=2){
console.log(x, y)
}
bar()//报错
参数的作用域在函数内部(如果参数是个函数,那么那个函数的作用域是它声明时所在的,下面再讲),x = y 因为y的声明在后面所以 会报错 它相当于
function bar(){
let x = y;
let y = 2; //y后声明的 所以 let x= y ;报错
console.log(x , y )
}
如果变成(y =2 , x= y )则不报错
然后看下若参数是函数的情况
想理解一个概念:函数的作用域是其声明时所在的作用域,如果A的参数是函数B,那么函数B的作用域不是函数A
let foo = 'outer';
function bar (func = x => foo){
let foo = 'inner';
console.log(foo)
}
bar() // outer
上面这个等于
let foo = 'outer';
let f = x => foo;
function bar(func = f) {
let foo = 'inner';
console.log(func()); // outer
}
bar();//outer
注意:let f = x => foo;
是箭头函数,也是ES6的内容之后会说,它相当于
let f = function(x){
return foo;
}
f函数实在 bar函数外面声明的,所以 他return foo 是外面的。
不允许重复声明
重复的声明会报错,之前用var 重复声明,后面的会覆盖前面的,但是使用let 则会报错。
function (val){
let val = 1;
} //报错 参数定义过一次了
function (val){
{
let val = 1;
}
}//不报错,因为里面的声明在一个独立的作用域汇中
块级作用域
function f1(){
let n = 5;
if(true){
let n = 10;
}
consol.log(n)
} //5
let n = 10 属于他在哪个if 作用域中,对面不没有影响。
const
const用来声明常量,一旦声明,敞亮的值就不能改变。
const PI = 3.1415
PI //3.1415
PI = 3.15
PI //3.1415
const PI = 3
PI //3.1415
可以看出不能改变常量的值,不过重新用const声明的时候不会像let那样报错,但也不起作用,只会默默地失败。 这句话是从别的地方看到的,不过我自己尝试了 无论是 直接PI=3;还是const PI = 3 都会报错,但报的错误不一样。 有可能是版本,或者浏览器版本等等的出现的不同吧, 不过大家还是要记住 常量不能重新定义(更改)
const与let一样 只在声明所在的块级作用域中有效,不存在变量提升,不可重复定义
const命令只是指向变量所在的地址
const foo = {}
foo.prop = 123;
foo.prop //123
foo={} //不起作用 会报错
foo存储的是一个地址,地址指向一个对象。
foo–>地址–>对象
对象能改变,但不能把foo在引向另一个地址。将一个对象声明为常量必须非常小心
全局对象属性
ES6 规定,var 命令和 function 命令声明的全局变量,属于全局对象的属性;let 命令、const 命令、class 命令声明的全局变量,不属于全局对象的属性。
var a = 1;
// 如果在node环境,可以写成global.a
// 或者采用通用方法,写成this.a
window.a // 1
let b = 1;
window.b // undefined