let const

let

  • 声明临时变量,在块级作用域
  • 不存在变量提升
  • 暂时性死区

    变量必须在声明后使用,不然会报错。称之为暂时性死区

  • 不允许重复声明

块级作用域

  • let 和 const增加了块级作用域
  • ES6允许块级作用域任意嵌套
  • ES5不允许函数声明在块级作用域中,但是ES6允许。但是由于历史包袱,建议避免在块级作用域中声明函数语句。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    	//不推荐
    // 函数声明语句
    {
    let a = 'secret';
    function f() {
    return a;
    }
    }
    ```
    #### const

    * const 声明一个只读的常量,一旦声明,不能更改。
    * 不存在变量提升
    * 不允许重复声明
    * 暂时性死区
    * 复合类型的常量,常量名不指向数据,而是指向数据所在的地址

    ### 解构 Destructuring
    ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构
    如果解构不成功,变量的值就等于undefined。



    #### 默认值

    * var [foo = true] = [];

    #### 对象的解构

    * var { foo, bar } = { foo: "aaa", bar: "bbb" };
    * 如果变量名与属性名不一致,必须写成下面这样。

    > var { foo: baz } = { foo: 'aaa', bar: 'bbb' };
    baz // "aaa"

    #### 字符串的解构

    * const [a, b, c, d, e] = 'hello';

    #### 数值和布尔值的解构

    let {toString: s} = 123;
    s === Number.prototype.toString // true

    let {toString: s} = true;
    s === Boolean.prototype.toString // true

    1
    2

    #### 函数形参的解构

    function add([x, y]){

    return x + y;
    

    }

    add([1, 2]);

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    #### 用途

    * 交换变量的值
    * 从函数返回多个值
    * 函数参数的定义
    * __提取JSON数据__
    * 函数默认值
    * 遍历Map结构
    * __输入模块的指定方法__

    ### 字符串的扩展

    * includes()
    * startsWith()
    * endWith()
    * 模板字符串

    abs${x}

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    ### 数值的扩展

    * 二进制(0b)八进制(0o)表示
    * Number.isFinite(obj) 是否为有限的
    * Number.isNaN(obj)
    * Number.isSafeNumber()

    ### 数组的扩展

    #### Array.from()

    将类似数组对象和可遍历的对象转化为数组

    * 类似数组对象:用length属性的对象
    * 可遍历对象: 具有Iterator接口
    * 扩展运算符也可以将可遍历对象转换为数组
    * Array.from(obj, function)的第二个参数function作用与map类似,可以对数组进行操作,返回一个新的数组。

    #### Array.of()
    将一组数值,转换为数组。

    `Array.of(3, 11, 8) // [3,11,8]`

    因为数组的构造函数Array存在下列不足

Array() // []
Array(3) // [, , ,]
Array(3, 11, 8) // [3, 11, 8]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

#### array#find()

没有时返回undefined。

#### array#includes()

#### array#entries(), array#keys(), array#values()

keys对键遍历,values对值进行遍历,entries对键值进行遍历

#### 数组的空位

数组的空位指,数组的某一个位置没有任何值。不同于undefined

ES5对空位的处理很不一致

* forEach(),filter(), every(),some都会跳过空位
* map会跳过空位,但是会保留这个值
* join()和toSting()会将空位视为undefined。

ES6明确将空位转为undefined。

* Array.from会将数组的空位转为undefined。
* copyWithin()会连空位一起拷贝
* fill()会将空位视为正常的数组位
* for...of循环也会遍历空位

### 对象的扩展

#### 属性的简洁表示法
ES6允许直接写入变量和函数,作为对象的属性和方法。

var foo = ‘bar’;
var baz = {foo};
baz // {foo: “bar”}

// 等同于
var baz = {foo: foo};

var o = {
method() {
return “Hello!”;
}
};

// 等同于

var o = {
method: function() {
return “Hello!”;
}
};

1
2
3

#### 属性名表达式
可以用表达式作为某个属性的属性名,这时表达式要放在方括号之内

// 方法一
obj.foo = true;

// 方法二
obj[‘a’ + ‘bc’] = 123;

1
* 属性名表达式和简洁表示法不能同时使用

// 报错
var foo = ‘bar’;
var bar = ‘abc’;
var baz = { [foo] };

1
2
3
4
5
6
7
8
9
10
11
12

#### 方法的name属性

函数的name属性,返回函数名称

#### Object.is()

ES5比较两个值是否相等,只有两个运算符:相等运算符(==)和严格相等运算符(===)。它们都有缺点,前者会自动转换数据类型,后者的NaN不等于自身,以及+0等于-0

ES5缺乏一种运算,在所有环境中,只要两个值是一样的,他们就相等。

ES6提出“Same-value equality”(同值相等)算法,用来解决这个问题。Object.is就是部署这个算法的新方法。它用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致。

Object.is(‘foo’, ‘foo’)
// true
Object.is({}, {})
// false

1
2

不同之处只有两个:一是+0不等于-0,二是NaN等于自身。

+0 === -0 //true
NaN === NaN // false

Object.is(+0, -0) // false
Object.is(NaN, NaN) // true

1
2
3
4
5
6
7
8
9
10
11
12
13

#### Object.assign()

Object.assign方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。

Object.assign方法的第一个参数是目标对象,后面的参数都是源对象。

* 如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。
* 由于undefinednull无法转成对象,所以如果它们作为参数,就会报错。
* Object.assign方法实行的是浅拷贝,而不是深拷贝。也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用

用法
* 为属性指定默认值

let options = Object.assign({}, DEFAULTS, options);
```
  • 合并多个对象
  • 克隆对象
  • 为对象添加方法
  • 为对象添加属性

属性的可枚举性

描述对象的enumerable属性成为「可枚举性」,如果该属性为false,某些操作会忽略当前属性。

ES5有三个操作会忽略enumerable为false的属性

  • for..in循环:遍历对象自身和继承的可枚举属性
  • Object.keys():返回对象自身的所有可枚举的属性键名
  • JSON.stringify():只串行化对象自身的可枚举属性

ES6新增了一个操作

  • Object.assign() 会忽略enumerable为false的属性,之拷贝对象自身的可枚举属性

属性的遍历

ES6一共有5种方法可以遍历对象的属性

  • for..in
  • Object.key(obj)
  • Object.getOwnPropertyNames(obj)
  • Object.getOwnPropertySymbols(obj)
  • Reflect.ownKeys(obj)


(1)类的实例属性

类的实例属性可以用等式,写入类的定义之中。

class MyClass {
myProp = 42;

constructor() {
console.log(this.myProp); // 42
}
}

(2)类的静态属性

类的静态属性只要在上面的实例属性写法前面,加上static关键字就可以了。

class MyClass {
static myStaticProp = 42;

constructor() {
console.log(MyClass.myProp); // 42
}
}

(3) let
块内临时变量

(4)const
常量,声明后必须立即赋值