logo头像
Snippet 博客主题

Es6基础

本文于1535天之前发表,文中内容可能已经过时。

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 // a is not defined;
b // 2
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]() //10
b[6]() //6
1
2
3
4
5
var tmp = 123;
if (true) {
console.log(tmp)
/*let 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(); // undefined f()函数相当于先var tmp变量提升了。
1
2
3
4
5
6
7
8
function f1() {
let n = 5;
if (true) {
let n = 10;
}
console.log(n); // 5
}
//如果把let改成var结果就是10;因为这是同一个作用域即函数作用域
1
2
3
4
5
6
var a=1;
function f() {
var a = 5;
}
f();
a //1 这里a的值没变化的原因因为是2个作用域,一个是全局,一个是函数
1
2
3
4
5
6
if(true){
function foo(){
}
}
//错误,es5中不能在块级作用域下声明函数,但是实际还是能够运行的。

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 //3.1415
Pi=4; //报错

1
2
3
4
if (true) {
console.log(MAX); // ReferenceError 因为不存在提升
const MAX = 5;
}
1
2
3
4
5
const foo = {};
foo.prop = 123; // 为 foo 添加一个属性,可以成功
foo.prop // 123
// 将 foo 指向另一个对象,就会报错
foo = {}; // TypeError: "foo" is read-only
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 //1
let b=1;
window.b //undefined

变量的解构赋值

箭头函数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; // 1990
var fn = (y) => {
return y - this.birth;
}
return fn.call({birth:2000}, year);
}
};
console.log(obj.getAge(2015)); // 25*/

方法写在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")
}
}
}
//区别就是如果写在constructor就相当于写在构造器里面,如果不写在constructor就相当于写在类的原型上面。