• ES6对象


    一、对象成员速写

    示例1
    const name = "xiaocan";
    const age = 23;
    const sayHello = function () {
      console.log(`my name is ${this.name}`);
    };
    // 过去的方式
    const user = {
      name: name,
      age: age,
      sayHello: sayHello,
    };
    
    // 速写
    const user = {
      name,
      age,
      sayHello,
    };
    
    user.sayHello();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    示例2
    // 以前的方式
    const myMath1 = {
      sum: function (a, b) {
        //...
      },
      random: function (min, max) {
        //...
      },
    };
    // 速写
    const myMath2 = {
      sum(a, b) {
        //...
      },
      random(min, max) {
        //...
      },
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    二、展开运算符

    示例1
    const arr = [1, 5, 34, 5, 21, 5];
    const result = Math.max(1, 5, 34, 5, 21, 5);  // Math.max(...arr)
    
    • 1
    • 2
    示例2
    const o1 = {
      a: 1,
      b: 2,
    };
    const o2 = {
      c: 3,
      d: 4,
    };
    // 对对象的展开
    const o3 = {
      ...o1,
      ...o2,
    };
    console.log(o3);   // { a: 1, b: 2, c: 3, d: 4 }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    示例3
    const arr = [1, 3, 4, 5];
    const arr1 = [42, 42, ...arr, 13];
    console.log(arr1); //[42,42,1,3,4,5,13]
    
    • 1
    • 2
    • 3
    示例4
    const user = {
      name: "小灿",
      age: 23,
    };
    const user2 = {
      ...user,
      name: "小灿同学",
    };
    console.log(user2);  // { name: '小灿同学', age: 23 }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    三、解构

    示例1
    const user = {
      name: "小灿",
      age: 23,
      address: {
        province: "广东",
        city: "深圳",
      },
    };
    const { name, age } = user;
    const {
      address: { city },
    } = user;
    console.log(name, age, city);  // 小灿 23 深圳
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    示例2
    const arr = [1, 2, 3, 4, 5];
    const [a, b, c] = arr;
    console.log(a, b, c); // 1 2 3
    const [, , d, , e] = arr;
    console.log(d, e); // 3 5
    const [, , f, ...arr2] = arr;
    console.log(f, arr2); // 3 [ 4, 5 ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    示例3
    let a = 1,
      b = 2;
    // 交换两个变量
    [b, a] = [a, b];
    console.log(b, a); // 1 2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    示例4
    // 在参数的位置对传入的对象进行解构
    function method({ a, b }) {
      console.log(a, b); // 1 2
    }
    const obj = {
      a: 1,
      b: 2,
      c: 3,
    };
    method(obj);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    示例5
    const users = [
      { name: "小灿同学", age: 23 },
      { name: "小灿", age: 23 },
    ];
    // 在遍历的时候进行解构
    for (const { name, age } of users) {
      console.log(name, age);
      // 小灿同学 23
      // 小灿 23
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    四、属性描述符

    对于对象中的每个成员,JS使用属性描述符来描述它们

    const users = { name: "小灿同学", age: 23 };
    
    • 1

    上面的对象,在JS内部被描述为

    {
      // 属性 name 的描述符
      name: {
        value: "小灿同学",
        configurable: true, // 该属性的描述符是否可以被重新定义
        enumerable: true, // 该属性是否允许被這历,会影响for-in循环
        writable: true, // 该属性是否允许被修改
      },
      // 属性 age 的描述符
      age: {
        value: 23,
        configurable: true, // 该属性的描述符是否可以被重新定义
        enumerable: true, // 该属性是否允许被這历,会影响for-in循环
        writable: true, // 该属性是否允许被修改
      },
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    ES5提供了一系列的API,针对属性描述符进行操作

    1. Object.getOwnPropertyDescriptor(obj, propertyName)

    该方法用于获取一个属性的描述符

    const user = { name: "小灿同学", age: 23 };
    console.log(Object.getOwnPropertyDescriptor(user, "name"));
    /**
    { 
      value: '小灿同学', 
      writable: true, 
      enumerable: true, 
      configurable: true 
    }
    */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    2. Object.defineProperty(obj, propertyName, descriptor)
    const user = { name: "小灿同学", age: 23 };
    Object.defineProperty(user, "name", {
      value: "小灿",
      writable: false, // 该属性不允许被修改
      enumerable: false, // 该属性是否允许被這历,for-in循环循环不出来,读取user也看不见user.name
      configurable: false, // 该属性的描述符不可以被重新定义
    });
    user.name = "xiaocantongxue";
    console.log(user); // { age: 23 }
    console.log(user.name); // 小灿
    
    for (const key in user) {
      if (Object.hasOwnProperty.call(user, key)) {
        console.log(key); // age, 遍历不到name
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    3. getter 和 setter

    属性描述符中有两个特殊的配置,分别为 get 和 set,通过它们,可以把属性的取值和赋值变为方法调用

    const obj = {};
    Object.defineProperty(obj, "a", {
      get() {
        // 读取属性a时,会运行该函数,得到的是该函数返回的值
        return 1;
      },
      set(val) {
        // 设置属性a时,会把val传值进去,调用该方法
        console.log(`执行了这句话,传进来的值是:${val}`);
      },
    });
    
    console.log(obj.a); // 1
    obj.a = 100; // 执行了这句话,传进来的值是:100
    console.log(obj.a); // 1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    const obj = {};
    let innerValue = 1;
    Object.defineProperty(obj, "a", {
      get() {
        // 读取属性a时,会运行该函数,得到的是该函数返回的值
        return innerValue;
      },
      set(val) {
        // 设置属性a时,会把val传值进去,调用该方法
        console.log(`将传进来的val值复制给innerValue变量`);
        innerValue = val;
      },
    });
    
    console.log(obj.a); // 1
    obj.a = 100; // 将传进来的val值复制给innerValue变量
    console.log(obj.a); // 100
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    五、键值对

    Object.keys(obj):获取对象的属性名组成的数组
    Object.values(obj):获取对象的值组成的数组
    Object.entries(obj):获取对象属性名和属性值组成的数组
    Object.fromEntries (entries):将属性名和属性值的数组转换为对象

    const user = { name: "小灿同学", age: 23 };
    
    console.log(Object.keys(user)); // [ 'name', 'age' ]
    console.log(Object.values(user)); // [ '小灿同学', 23 ]
    console.log(Object.entries(user)); // [ [ 'name', '小灿同学' ], [ 'age', 23 ] ]
    console.log(
      Object.fromEntries([
        ["name", "小灿同学"],
        ["age", 23],
      ])
    ); // { name: '小灿同学', age: 23 }
    
    /**
      打印:
      name: '小灿同学'  
      age: 23
     */
    
    for (const [key, value] of Object.entries(user)) {
      console.log(`${key}: ${value}`);
      /**
        name: '小灿同学'  
        age: 23
      */
    }
    
    • 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

    六、冻结

    使用 Object.freeze(obj)可以冻结一个对象,该对象的所有属性均不可更改

    const obj = {
      a: 1,
      b: 2,
      c: {
        d: 3,
      },
    };
    Object.freeze(obj); //冻结对象obj
    obj.a = "a"; // 不报错,代码无效
    obj.b = "b"; // 不报错,代码无效
    delete obj.a; // 不报错,代码无效
    obj.c = "c"; // 不报错,代码无效
    
    obj.c.d = "d"; // 对象c没有被冻结,有效
    
    console.log(obj);  // { a: 1, b: 2, c: { d: 'd' } }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    可以使用 Object.isFrozen 来判断一个对象是否被冻结

    七、相同性判断

    Object.is 方法,可以判断两个值是否相同,它和===的功能基本一致,区别在于:

    • NaN和NaN相等
    • +0和-0不相等
    console.log(Object.is(1, 2)); // false
    console.log(Object.is("1", 1)); // false
    console.log(Object.is(NaN, NaN)); // true
    console.log(Object.is(+0, -0)); // false
    
    • 1
    • 2
    • 3
    • 4

    八、Set

    set是一种数据集合,用于保存一系列唯一的值
    MDN参考

    1.数组去重
    // Use to remove duplicate elements from the array
    const numbers = [2, 3, 4, 4, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 5, 32, 3, 4, 5];
    console.log([...new Set(numbers)]);  // [2, 3, 4, 5, 6, 7, 32]
    
    • 1
    • 2
    • 3

    八、Map

    Map是一种数据集合,用于保存一系列键值对(key-value pair),其中,键(key)可以是任何类型,并且是唯一的
    MDN参考

    九、练习题

    练习题1
    const obj = {
      a: 1,
      b: 2,
      c: 3,
    };
    // 遍历对象的所有属性名
    for (const key of Object.keys(obj)) {
      console.log(key);
    }
    
    // 遍历对象的所有属性值
    for (const value of Object.values(obj)) {
      console.log(value);
    }
    
    // 遍历对象的所有属性名和属性值
    for (const [key, value] of Object.entries(obj)) {
      console.log(key, value);
    }
    
    // 复制obj的所有属性到一个新的对象
    const newObj = {
      ...obj,
    };
    console.log(newObj);
    
    // 复制obj除a以外的所有属性到一个新的对象
    const { a, ...removeAObj } = newObj;
    console.log(removeAObj);
    
    • 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
    练习题2
    // 根据下面的调用和注释,完成函数 createOptions
    
    function createOptions(options) {
      options = options || {};
      const defaultOptions = { time: 1000, speed: 50, text: "" };
      return {
        ...defaultOptions,
        ...options,
      };
    }
    
    console.log(createOptions()); // { time: 1000, speed: 50, text: '' }
    
    console.log(
      createOptions({
        time: 500,
      })
    ); // { time: 500, speed: 50, text: '' }
    
    console.log(
      createOptions({
        time: 500,
        text: "hello world",
      })
    ); // { time: 500, speed: 50, text: 'hello world' }
    
    • 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
    练习题3
    // 遍历对象 user, 将其每一个属性变为 getter 和 setter, 保持读写功能不变
    // 读取属性时,输出:正在读取xxx属性,值为xxx
    // 给属性赋值时,输出:正在设置xxx属性,新的值为xxx
    const user = {
      name: "小灿同学",
      age: 23,
      sex: "male",
    };
    
    for (let [key, innerValue] of Object.entries(user)) {
      Object.defineProperty(user, key, {
        get() {
          console.log(`正在读取 ${key} 属性,值为${innerValue}`);
          return innerValue;
        },
        set(val) {
          innerValue = val;
          console.log(`正在设置 ${key} 属性,设置为${innerValue}`);
        },
      });
    }
    user.name; // 正在读取 name 属性,值为小灿同学
    user.name = "小灿"; // 正在设置 name 属性,设置为小灿同学
    user.name; // 正在读取 name 属性,值为小灿
    
    user.age; // 正在读取 age 属性,值为23
    user.age = 22; // 正在设置 age 属性,设置为23
    user.age; // 正在读取 age 属性,值为22
    
    user.age += 10; // 正在读取 age 属性,值为22      正在设置 age 属性,设置为32
    
    • 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

    笔记整理自渡一教育袁老师课堂

  • 相关阅读:
    VMware安装与配置Linux 虚拟机
    Nginx Note03——异步非阻塞机制
    [附源码]Python计算机毕业设计SSM考试排考系统(程序+LW)
    大数据-73 Kafka 高级特性 稳定性-事务 相关配置 事务操作Java 幂等性 仅一次发送
    基于java(ssm)学生在线课程学习系统源码(java毕业设计)
    2023第十二届中国智能产业高峰论坛
    【Linux】网络编程基础
    C#WPF命令行参数实例
    golang学习笔记系列之基本数据类型
    iOS——类与对象底层探索
  • 原文地址:https://blog.csdn.net/weixin_45463061/article/details/126524216