let和const
let
1 . let 命令
1.1 let和var2个用法类似,但是申明的变量只在let命令所在的代码块有效
1.2 let在for循环里面是一个局部变量,不存在变量提升。但是这里有一个例外就是函数,如果声明的是函数还是会变量提升的。
1.3 只要块级作用域存在let,它申明的变量就绑定这个区域,不受外面的影响。如果在申明之前使用就会报错,
语法上将这就是”暂时性死区”。这样设计就是让大家养成习惯,变量一定要在声明后使用参考案例3
1.4 let不允许在相同作用域内,声明同一个变量。
1 2 3 4 5 6
| { let a=1; var b=2; } a b
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| var a=[]; var b=[]; for(var i=0;i<10;i++){ a[i]=function(){ console.log(i); } } for(let i=0;i<10;i++){ b[i]=function(){ console.log(i); } } a[6]() b[6]()
|
1 2 3 4 5
| var tmp = 123; if (true) { console.log(tmp) }
|
1 2
| let tmp = 123; let tmp = 2
|
2 . 块级作用域
2.1 Es5里面只有全局作用域和函数作用域,没有块级作用域,会导致错误比如内层变量会覆盖外层变量
2.2 会造成内存泄露,比如for循环里面i声明之后就一直存在于内存中,不会被销毁,造成泄露。
2.3 es5规定行数只能在顶级作用域和函数作用域中声明,不能在块级作用域下声明,但是es6,可以在块级作用域下声明变量,但是类似于let,在该作用域外不可引用。这个规则在浏览器外适用,但是浏览器可以不遵循这个规则
2.4 es6允许在块级作用域内声明函数,函数声明类似于var,会被提升到全局作用域或者函数作用域的头部,同时函数声明也会被提升到所在块级作用域的头部
2.5 一般情况下块级作用域是没有返回值的,现在有议案,是在块级作用域之前加上do,使它变成do表达式,这样块级作用域就可以有返回值了。
1 2 3 4 5 6 7 8
| var tmp = new Date(); function f() { console.log(tmp); if (false) { var tmp = 'hello world'; } } f();
|
1 2 3 4 5 6 7 8
| function f1() { let n = 5; if (true) { let n = 10; } console.log(n); }
|
1 2 3 4 5 6
| var a=1; function f() { var a = 5; } f(); a
|
1 2 3 4 5 6
| if(true){ function foo(){ } }
|
const
1 . 基本用法
1.1 声明一个只读的常量,一旦声明,这个值就不能被改变。
1.2 const声明的时候必需要赋值,不赋值就会报错。
1.3 const和let一样声明的常量不能提升,同样存在暂时性死区,只能在声明的位置后面使用。
1.4 const声明的是常量的时候,值在栈里面,固定不变了,但是如果是引用类型的,变量是一个内存地址,const只能保证指针是固定的,至于它指向的数据结构就不能控制了。
1.5 如果想要冻结对象,可以使用Object.freeze,这样就不能对对象赋值了。
1.6 声明变量一共有6种形式,var function let const class import
1 2 3
| const Pi=3.1415; Pi Pi=4;
|
1 2 3 4
| if (true) { console.log(MAX); const MAX = 5; }
|
1 2 3 4 5
| const foo = {}; foo.prop = 123; foo.prop foo = {};
|
1 2 3
| const foo = Object.freeze({}); foo.prop = 123; foo
|
顶级对象的属性和全局对象 global和window
1.1 Es5顶层对象的属性和全局变量是等价的,Es6开始var和function命令声明的全局变量依然是顶层对象的属性,但是let、const、class声明的全局变量不属于顶层对象的属性
1.2 在浏览器中顶层对象是window,而node、web work的顶层对象是global,浏览器和web worker中self指向顶层对象,但是node没有self。
1.3 函数里面的this,如果是单纯当作函数运行,this指向的是顶层对象,但是在严格模式下this返回的是undefined
1 2 3 4
| var a=1; window.a let b=1; window.b
|
变量的解构赋值
箭头函数this指向不一样,es5如果在函数内部写函数的情况下,内部的函数中this指向的是window或者undefined,但是es6中this指向的是外面的那个函数。
1 2 3 4 5 6 7 8 9 10 11
| var obj = { birth: 1990, getAge: function (year) { var b = this.birth; var fn = (y) => { return y - this.birth; } return fn.call({birth:2000}, year); } }; console.log(obj.getAge(2015));
|
方法写在constructor里面和外面的区别
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class Father { speak(){ alert("a") } } class Father2 { constructor(){ this.speak=()=>{ alert("b") } } }
|