0%

15

自动摘要: 1.let与const 1.let命令 1.所声明的变量,只在let命令所在的代码块内有效(for循环的计数器,很适合使用let命令) 2.不存在变量提升,变量需 ……..

  1. let与const
    1. let命令
      1. 所声明的变量,只在let命令所在的代码块内有效(for循环的计数器,很适合使用let命令)
      2. 不存在变量提升,变量需要在声明之后才能使用
      3. 暂时性死区(temporal dead zone TDZ),只要在块级作用域内存在let命令,它所声明的变量就绑定这个区域,不受外部影响,在代码块内,使用let命令声明变量前,该变量都是不可用的。
      4. 不允许重复声明,不允许在相同作用域内,重复声明同一个变量
    2. 块级作用域
      1. ES6在5的基础上增加了块级作用域
      2. ES6允许块级作用域的任意嵌套
      3. 内层作用域可以定义外层作用域的同名变量
      4. 以下三天规则只对ES6的浏览器实现有效,其他环境的实现不用遵守,还是将块级作用域的函数声明当作let处理
        1. 允许在块级作用域内声明函数
        2. 函数声明类似于var,即会提升到全局作用域或函数作用域的头部
        3. 同时,函数声明还会提升到所在的块级作用域的头部
      5. 考虑到环境导致的行为差异太大,应该避免在块级作用域内声明函数。如果确实需要,应该写成函数表达式,而不是函数声明语句(块级作用域内部,优先使用函数表达式)
      6. ES6的块级作用域必须有大括号,如果没有大括号,JavaScript引擎就认为不存在块级作用域
    3. const命令
      1. 声明一个只读常量,常量的值不能改变(本质:const实际上保证的,不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。对于简单的数据比如数值,字符串,布尔值。值就保存在变量指向的那个内存地址,因此等同于常量。但是对于复合类型的数据,主要是对象和数组。变量指向的内存地址,保存的只是一个指向实际数组的指针,const只能保证这个指针是固定的,即总是指向另一个固定的地址,至于它指向的数据结构是不是可变的,就完全不能控制了。所以使用const声明复杂类型数据时就要慎重)
        1. 如果常量是对象或数组,则常量存储的是一个地址,这个地址指向一个对象。不可变的是这个地址,即不能把常量指向另一个地址,但是对象本身是可以改变的,所以依然可以为其添加新的属性
1
2
3
4
const foo = {};
foo.push("hello"); //可执行
foo.length = 0; //可执行
a = ["Dave"]; //报错
     2. 如果真的想冻结对象,可以使用Object.freeze方法
1
2
3
4
5
const foo = Object.freeze({})

// 常规模式时,下面一行不起作用
// 严格模式时,该行会报错
foo.prop = 123;
  2. const声明必需初始化常量,必需赋值
  3. const作用域只在声明所在的块级作用域内有效;
  4. 也存在暂时性死区
  1. ES6一共有六种声明变量的方法:var、function 、let 、const 、import 、class
  2. 解构赋值
    1. 解构赋值是对赋值运算符的扩展,是一种针对数组或者对象进行模式匹配,然后对其中的变量进行赋值

    2. 解构模型:解构的目标 = 解构的源 (解构的目标,解构赋值表达式的左边部分,解构的源是解构赋值表达式的右边部分)

    3. 数组模型的解构(Array)

      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
      41
      42
      43
      // 基本
      let [a,b,c] = [1,2,3];
      // a=1
      // b=2
      // c=3

      // 可嵌套
      let [a,[[b],c]] = [1,[[2],3]];
      // a=1
      // b=2
      // c=3

      // 可忽略
      let [a, ,b] = [1,2,3];
      // a=1
      // b=3

      // 不完全解构
      let [a=1,b] =[];
      // a=1
      // b=undefined

      // 剩余运算符
      let [a,...b] = [1,2,3];
      // a=1;
      // b=[2,3]

      // 字符串
      let [a,b,c,d,e] = "hello"
      // a='h'
      // b='e'
      // c='l'
      // d='l'
      // e='o'

      // 解构默认值
      let [a=2] = [];
      // a=2

      // 当解构模式有匹配结果,且匹配结果是undefined时,会触发默认值作为返回结果
      let [a=3,b=a] = []; // a=3,b=3
      let [a=3,b=a] = [1]; // a=1,b=1
      let [a=3,b=a] = [1,2]; // a=1,b=2
    4. 对象模型的解构(Object)

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
// 基本
let {foo,bar} = {foo: 'aaa', bar: 'bbb'};
// foo = 'aaa'
// bar = 'bbb'

let {baz : foo} = {baz: 'ddd'}
// foo = 'ddd'

// 可嵌套
let obj = {p:['hello',{y:'world'}]};
let {p: [x,{y}]} = obj;
// x = 'hello'
// y = 'world'

// 可忽略
let obj = {p: ['hello',{y: 'world'}]};
let {p: [x,{}]} = obj;
// x = 'hello'

// 不完全解构
let obj = {p: [{y: 'world'}]};
let {p : [{y},x]}= obj;
// x = undefined
// y = 'world'

// 剩余运算符
let {a,b,...rest} = {a:10,b:20,c:30,d:40};
// a = 10
// b = 20
// rest = {c:30,d:40}

// 解构默认值
let {a=10,b=5} = {a:5}
// a = 5;b=5
let {a:aa = 10, b:bb = 5} = {a:3};
// aa = 3; bb=5
  1. Symbol

** 数据类型Symbol表示独一无二的值**

  1. 基本用法
    tips
    let sy = Symbol(“KK”);console.log(sy); // Symbol(KK)typeof(sy); // “symbol”
  • Symbol 函数栈不能用new命令,因为Symbol是原始数据类型,不是对象。可以接受一个字符串作为参数,为新创建的Symbol提供描述,用来显示在控制台或者作为字符串的时候使用,便于区分。
  • 相同参数Symbol()返回的值不相等
  1. 使用场景

    1. 可以用作属性名,因为Symbol的值都是不相等的,所以可以保证属性的不重名
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      let sy = Symbol("key1");

      // 写法1
      let syObject = {};
      syObject[sy] = "kk";
      console.log(syObject); // {Symbol(key1): "kk"}

      // 写法2
      let syObject = {
      [sy]: "kk"
      };
      console.log(syObject); // {Symbol(key1): "kk"}


      let syObject = {};
      syObject[sy] = 'kk';

      syObject[sy]; // "kk"
      syObject.sy; // undefined
      💡 Symbol作为对象的属性名时,不能用 . 运算符,要用方括号,因为 . 运算符后面是字符串,所以取到的是字符串sy属性,而不是Symbol值sy属性。
  2. 注意点

    1. Symbol 值作为属性名时,该属性是公有属性不是私有属性,可以在类的外部访问。但是不会出现在 for…in 、 for…of 的循环中,也不会被 Object.keys() 、 Object.getOwnPropertyNames() 返回。如果要读取到一个对象的 Symbol 属性,可以通过 Object.getOwnPropertySymbols() 和 Reflect.ownKeys() 取到。
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      let syObject = {};
      syObject[sy] = "kk";
      console.log(syObject);

      for (let i in syObject) {
      console.log(i);
      } // 无输出

      Object.keys(syObject); // []
      Object.getOwnPropertySymbols(syObject); // [Symbol(key1)]
      Reflect.ownKeys(syObject); // [Symbol(key1)]
  3. Symbol.for()

    1. 类似单例模式,首先会在全局搜索被登记的Symbol中是否有该字符串参数作为名称的Symbol值,如果有即返回该Symbol值,若没有则新建并返回一个以该字符串参数为名称的Symbol值,并登记在全局环境中供搜索
  4. Symbol.keyFor()

    1. 返回一个已登记的Symbol类型值得key,用来检测该字符串参数作为名称得Symbol值是否已被登记
  5. 函数

    1. 函数参数的扩展
      1. 默认参数:注意在使用默认参数时,不允许有同名参数

      2. 只有在未传递参数,或者是参数为undefined时,才会使用默认参数,null值被认为是有效的值传递

      3. 函数参数默认值存在暂时性死区,在函数参数默认值表达式中,还未初始化赋值的参数值无法作为其他参数的默认值。

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        function f(x,x=y){
        console.log(x,y)
        }
        f(1); // 1,1

        function f(x=y){
        console.log(x);
        }
        f(); //ReferenceError: y is not defined


        // 不定参数
        function f(...values){
        console.log(values.length);
        }
        f(1,2); // 2
        f(1,3,5,6); //4
      4. 不定参数:用来表示不确定参数个数。形如:…变量名。由…加上一个具名参数标识符组成,具名参数标识符只能放在最后,并且有且只有一个不定参数

    2. 箭头函数
      1. 更加简洁的函数书写方式
      2. 语法:参数=>函数体
      3. 当箭头函数没有参数或有多个参数,要用()括起来
      4. 当箭头函数函数体有多行语句,要用{},表示代码块,当只有一行语句,并且需要返回结果时,可以省略{},结果会自动返回
      5. 当箭头函数要返回对象时,为了区分于代码块,要用()将对象括起来
      6. 注意点:没有this、supper、arguments和new.target绑定
      7. 箭头函数体中的 this 对象,是定义函数时的对象,而不是使用函数时的对象。
      8. 使用场景:需要维护一个this上下文的时候,就可以使用箭头函数
  6. 字符串

    1. 字符串识别
      1. includes():返回布尔值,判断是否找到参数字符串
      2. startsWith():返回布尔值,判断参数字符串是否在原字符串的头部
      3. endsWith():返回布尔值,判断参数字符串是否在原字符串的尾部。
    2. 以上方法都可以接受两个参数,一个是需要搜索的字符串,一个是可选的搜索起始位置索引
    3. 这三个方法只返回布尔值,如果需要知道子串的位置,还是得用indexOf和lastIndexOf
    4. 字符串重复:repeat():返回新的字符串,表示将字符串重复指定次数返回。如果参数是小数,向下取整,如果参数是NaN,等同于零次,如果参数是负数或者Infinity,会报错。如果传入的参数是字符串,会先将字符串转化为数字。
    5. 字符串补全:
      1. padStart:返回新的字符串,表示用参数字符串从头部(左侧)补全原字符串
      2. padEnd:返回新的字符串,表示用参数字符串从尾部(右侧)补全字符串
      3. 以上两个方法接受两个参数,一个是指定生成的字符串的最小长度,第二个参数是用来补全的字符串
        • 如果没有第二个参数,默认用空格补全。
        • 如果指定的长度小于或等于字符串长度,则返回原字符串;
        • 如果原字符串加上补全字符串的总长度大于指定长度,则截去超出位数的补全字符串
    6. 模板字符串:
      1. 相当于加强版的字符串,用反引号 ` 。除了作为普通字符串,还可以用来定义多行字符串,还可以在字符串中加入变量和表达式
      2. 字符串插入变量和表达式,变量名写在${}中,${}中可以放入JavaScript表达式
      3. 字符串中也可以调用函数
      4. 注意:模板字符串中的换行和空格都是会被保留的
        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
        // 普通字符串
        let string = `Hello'\n'world`;
        console.log(string);
        // Hello'
        // 'world

        //多行字符串
        let string = `Hey,
        Can you stop angry now?`;
        console.log(string);
        // Hey
        // Can you stop angry now?

        // 字符串中加入变量和表达式
        let name = "Anne";
        let age = 17;
        let string = `My name is ${name},I am ${age+1} years old next year.`;
        console.log(string);
        // My name is Anne,I am 18 years old next year.

        // 字符串中调用函数
        function f(){
        return "have fun";
        }
        let string = `Good Game! ${f()}`;
        console.log(string)
        // Good Game! have fun
  7. Map 与 Set

    1. Map对象保存的是键值对,任何值(对象或者原始值)都可以作为一个键或一个值

    2. Maps和Objects区别

      1. Object的键只能是字符串或者Symbols,但是一个Map的键可以是任意值
      2. Map中的键值是有序的(FIFO原则),而添加到对象Object中的键则不是
      3. Map的键值对个数可以从size属性获取,而Object的键值对个数只能手动计算
      4. Object都有自己的原型。
    3. Map的遍历

      1. for….of
      2. forEach()
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        var myMap = new Map();
        myMap.set(0,"zero");
        myMap.set(1,"one");

        // for...of
        for(var [key,value] of myMap){
        console.log(key+ "=" +value);
        }
        // forEach()
        myMap.forEach(function(key,value){
        console.log(key+"="+value);
        },myMap)

    4. Map对象的操作

      1. Map与Array的转换
        1. Map构造函数可以将一个二维键值对数组转换成一个Map对象
          1. var myMap = new Map(kvArray)
        2. 使用Array.from函数可以将一个Map对象转换成一个二维键值对数组
          1. var outArray = Array.from(myMap)
      2. Map的克隆
        1. var myMap2 = new Map(myMap1)
        2. Map克隆之后生成新的对象。两个对象不相等
      3. Map的合并
        1. 合并两个Map对象时。有重复的键值,则后面的会覆盖前面的.
      4. Set对象:允许存储任何类型的唯一值,无论是原始值或者是对象引用
        1. Set对象存储的值总是唯一的
        2. +0 与 -0在存储判断唯一性的时候是恒等,所以不重复
        3. undefined 与undefined是恒等的,所以不重复
        4. NaN 与 NaN是不恒等的,但是Set只能存一个,所以不重复
        5. 类型转换 var mySet = new Set([“value1”, “value2”, “value3”]);
          1. Array转Set:var myArray = […mySet];
          2. String转Set:var mySet = new Set(‘hello’)
          3. 在Set中toString方法是不能将Set转换成String
        6. Set对象作用
          1. 数组去重
          2. 并集
          3. 交集
          4. 差集
  8. Promise对象

    1. 是异步编程的一种解决方案。Promise是一个对象,从它可以获取异步操作的信息。
  • 本文作者: SindreYang
  • 本文链接: http://blog.mviai.com/2025/15._ES6/
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

欢迎关注我的其它发布渠道