JavaScript ES6 - 对象扩展

Posted 黑木令

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript ES6 - 对象扩展相关的知识,希望对你有一定的参考价值。

本章节的主要内容是: ES6 对象扩展

: 对象扩展
    1. 属性的简洁表示方法
    2. 属性表达式
    3. 扩展运算符
    4. Object 新增方法

如图所示:

1. ES6 属性的简洁表示方法:

/**
1.1 普通属性
 */
// ES5 对象写法

  // 示例一
  let str1 = '字符'
  let num1 = 11111
  let objES5 = 
    str1: str1,
    num1: num1
  
  console.log('ES5 对象写法: ', objES5); // ES5 对象写法:  str1: '字符', num1: 11111

// ES6 写法

  // 示例一
  // 对比 ES5 对象写法中的 '示例一', 它们的结果并没有什么不同, 只是写法上更加简洁 。
  let str1 = '字符'
  let num1 = 11111
  let objES6 = 
    str1,
    num1
  
  console.log('ES6 对象写法: ', objES6); // ES6 对象写法:  str1: '字符', num1: 11111



/**
1.2 对象中的方法
    1. ES6 中的写法比 ES5 中的写法简洁的多: 我们可以将 " : 与 function " 关键字省去 。
 */
// ES5 写法

  let es5_method = 
    hello: function() 
      console.log('ES5 中方法的写法 -- 使用方法对比是否不同 (ES5)');
    
  
  es5_method.hello() // ES5 中方法的写法 -- 使用方法对比是否不同 (ES5)

// ES6 写法

  let es6_method = 
    hello() 
      console.log('ES6 中方法的写法 -- 使用方法对比是否不同 (ES6) ');
    
  
  es6_method.hello() // ES6 中方法的写法 -- 使用方法对比是否不同 (ES6)



/**
1.3 函数返回值
 */

  function fun1() 
    let x = 1
    let y = 2
    // ES6 写法
    return x, y

    // // ES5 实现方法
    // return 
    //   x: x,
    //   y: y
    // 
  
  console.log(fun1()); // x: 1, y: 2



/**
1.4 CommonJS 模块输出变量
 */
// 假设下面的代码是一个 .JS 文件中的内容, 使用 CommonJS 模块化方法输出内容

  var ms = a: 1
  function fn1() 
    return 1 + 2
  
  function fn2() 
    return 2+3
  
  function fn3() 
    ms = 
  
  // moudle.exports = 
  //   ms,
  //   fn1,
  //   fn2,
  //   fn3
  // 

2. 属性名表达式: []

/**
2. 属性名表达式: []
   1. 在 ES5 中, 对象的 key 值是固定的; 在 ES6 中 key 值是可以用表达式也可以使用变量来作为 key 使用的 。
   2. 注意细节知识点:
      1. '属性名表达式' 与 '简介表示法' 不能同时使用, 否则会报错 。
 */
// ES5 写法

  let a = 'abc'
  let es5_obj = 
    a: 'ddddd'
  
  console.log(es5_obj); // a: 'ddddd'


// ES6 写法

  let a = 'abc'
  let es6_obj = 
    // 字面量定义对象的属性名
    [a]: 'ddddd',

    // 表达式作为对象的属性名
    ['k' + 'ey' + 'Val']: 'kkkkk',

    // 表达式用于定于方法名
    ['f' + 'un' + '1']() 
      return '表达式用于定于方法名'
    
  
  console.log(es6_obj); // abc: 'ddddd', keyVal: 'kkkkk', fun1: ƒ

3. ES6 对象扩展运算符: …

/**
3. 扩展运算符 ...
   1. 结构赋值:
      1. 对象的解构赋值用于从一个对象取值, 相当于将所有可遍历的、但尚未被读取的属性分配到指定的对象上 。
      2. 注意:
         1. 对象的解构赋值要求等号右边是一个对象; 如果等号右边是 undefined 或 null 会报错, 因为它们不能转换为对象 。
         2. 解构赋值的复制是浅复制 。
   1. 注意:
      1. 为了正常运行当前语法, 我们需要安装: cnpm install babel-preset-stage-2 --save; 在 .babelrc 文件中 presets 选项中, 添加 "stage-2" 。
      2. 通常安装到 stage-2 就够用了, 如果还不行, 再安装 stage-1 或者 stage-0 <越小越新> 。
   1.
 */


  // 解构赋值:
  let a, b, ...c = a: '1', b: '2', c: '3', d: '4'
  console.log('对象的扩展运算符: ', c); // 对象的扩展运算符:  c: '3', d: '4'


  // undefined 或 null 会报错
  // let a1, b1, ...c1 = undefined // 报错
  // let a2, b2, ...c2 = null // 报错


  // 解构赋值的复制是浅复制


4. ES6 Object 新增方法

4.1 ES6 新增方法: Object.is()

/**
4.1 Object.is()
    1. 判断两个值是否相等
 */

  console.log('判断两个字符串是否相等: ', 'ES6: ', Object.is('abc', 'abc'), 'ES5: ', 'abc' === 'abc'); // 判断两个字符串是否相等:  ES:  true ES5:  true

  /**
   * 1. 数组是引用类型, 虽然都是空数组, 在值上都是空, 但是这两个数组引用的是两个不同的地址, 所以在严格意义上来讲它们是不相等的 。
   * 2. Object.is() 的功能与 ===(严格相等运算符) 的功能没有区别 。
   */
  console.log('判断两个数组是否相等<引用类型>', 'ES6: ', Object.is([], []), 'ES5: ', [] === []); // 判断两个数组是否相等<引用类型> ES6:  false ES5:  false

4.2 ES6 新增方法: Object.assign()

/**
4.2 Object.assign()
    1. 拷贝功能
    2. 细节知识点:
       1. Object.assign 实现的是浅拷贝  。
          1. 浅拷贝只拷贝引用地址, 而不是将值真正的拷贝过去 。
          2. 这个方法拷贝的只是自身的属性, 如果这个对象还有继承属性, 它是不会拷贝继承属性的 。
          3. 同时也不能拷贝不可枚举的属性 。
 */

  let obj1 = a: 'a'
  let obj2 = b: 'b'
  let objAss = Object.assign(obj1, obj2)
  console.log('拷贝功能: ', objAss, obj1, obj2); // 拷贝功能:  a: 'a', b: 'b' a: 'a', b: 'b' b: 'b'
  // 修改
  obj2.b = '111111111'
  console.log('修改: 单层深拷贝 ----- : ', objAss, obj1, obj2) // 修改 ----- :  a: 'a', b: 'b' a: 'a', b: 'b' b: '111111111'

  // 源对象属性的值为对象 <Object.assign 不算是真正的深拷贝>
  let a1 = a: '111'
  let a2 = b: '222', c: d: '3333'
  let asA = Object.assign(, a1, a2)
  console.log(asA, a1, a2); // a: '111', b: '222', c: d: '3333' a: '111' b: '222', c: d: '3333'
  a2.c.d = '修改属性值为对象的结果---3333'
  console.log(asA, a1, a2); // a: '111', b: '222', c: d: '修改属性值为对象的结果---3333' a: '111' b: '222', c: d: '修改属性值为对象的结果---3333'



  // 注意: 如果目标对象与源对象有同名属性, 或者多个源对象有同名属性, 则后面的属性会覆盖前面的属性
  let o1 = a:1, b:2
  let o2 = b: 3, c: 4
  let o3 = c: 5
  Object.assign(o1, o2, o3)
  console.log('属性覆盖 -- o1: ', o1); // 属性覆盖 -- o1:  a: 1, b: 3, c: 5


  // 如果只有一个参数, Object.assign 会直接返回该参数
  let b1 = a: 2
  console.log('只有一个参数 -- b1: ', Object.assign(b1) === b1); // 只有一个参数 -- b1:  true




// 为对象添加属性:

  class Point 
    constructor(x, y) 
      // 通过 Object.assign 方法将 x 、 y 属性添加到 Point 类的对象实例中 。
      Object.assign(this, x, y)
    
  
  // let point = new Point
  // console.log(point.x);




// 为对象添加方法:

  class SomeClass 
  Object.assign(SomeClass.prototype, 
    // 直接将两个函数放在大括号中, 使用 Object.assign 方法添加到 SomeClass.prototype 中
    someMethod(arg1, arg2) 

    ,
    anotherMethod() 

    

  )

6. ES6 Object.getOwnPropertyDescriptor()

/**
5. Object.getOwnPropertyDescriptor()
   1. 可以获取属性的描述对象 。

   1. 属性的可枚举型:
 */

  let obj1 = foo: 123
  console.log(Object.getOwnPropertyDescriptor(obj1, 'foo'));
  // 打印结果:
  // 
  //   value: 123,
  //   writable: true, // 对象属性是否可修改; flase 为不可修改, 默认值为 true 。
  //   enumerable: true, // 可枚举型; 如果为 false, 某些操作可以忽略当前属性 。
  //   configurable: true // 能否使用 delete / update, 能否需改属性特性 、 或能否修改访问器属性; false 为不可重新定义, 默认值为 true 。
  // 
  /**
   * 1. Object.assign 会忽略 enumerable 为 false 的属性, 只赋值对象的可枚举属性 。
   * 2. 注意:
   *    1. ES6 规定, class 的原型的方法都是不可枚举的 。
   */

7. ES6 属性的遍历

/**
6. 属性的遍历
   1. for...in    : 循环遍历对象自身和继承的可枚举属性(不含 Symbol 属性) 。
   2. Object.keys(obj)    : 返回数组; 对象自身<不包含继承>和可枚举属性(不含 Symbol 属性) 。
   3. Object.getOwnPropertyNames(obj)    : 返回数组; 包含自身的所有属性 <不含 Symbol 属性, 但是包含不可枚举的属性> 。
   4. Object.getOwnPropertySymbols(obj)  : 返回一个数组; 包含自身所有的 Symbol 属性 。
   5. Reflect.ownKeys(obj)   : 返回一个数组; 包含对象自身的所有属性, 不管属性名是 Symbol 还是字符串, 也不管是否可枚举 。

   细节知识点:
   1. Object.keys() 与 Reflect.ownKeys() 的区别:
      1. Object.keys() 返回属性 key, 但不包括不可枚举的属性 。
      2. Reflect.ownKeys() 返回所有属性 key 。
 */

  let obj = 
    a: 1,
    b: b1: 2,
    c: [3, 4],
    d: 
      d1: 5,
      d2: d3: 6,
      d4: d5: [7,8]
    ,
    [Symbol()]: 123
  
  // for...in
  for (const key in obj) 
    if (Object.hasOwnProperty.call(obj, key)) 
      console.log('属性的遍历--for...in: ', key);
      // // 打印结果:
      // 属性的遍历--for...in:  a
      // 属性的遍历--for...in:  b
      // 属性的遍历--for...in:  c
      // 属性的遍历--for...in:  d
    
  

  // Object.keys(obj)
  console.log('属性的遍历--Object.keys: ', Object.keys(obj)); // 属性的遍历--Object.keys:  ['a', 'b', 'c', 'd']

  // Object.getOwnPropertyNames
  console.log('属性的遍历--Object.getOwnPropertyNames: ', Object.getOwnPropertyNames(obj));
  // 打印结果:
  // 属性的遍历--Object.getOwnPropertyNames:  ['a', 'b', 'c', 'd']

  // Object.getOwnPropertySymbols
  console.log('属性的遍历--Object.getOwnPropertySymbols: ', Object.getOwnPropertySymbols(obj));
  // 打印结果:
  // 属性的遍历--Object.getOwnPropertySymbols:  [Symbol()]

  // Object.ownKeys
  console.log('属性的遍历--Reflect.ownKeys: ', Reflect.ownKeys(obj));
  // 打印结果:
  // 属性的遍历--Reflect.ownKeys:  ['a', 'b', 'c', 'd', Symbol()]

8. keys() / values() / entries()

/**
7. keys() / values() / entries() : 用于遍历对象 <与数组的 keys() / values() / entries() 用法相同, 可参考数组中的用法>
   1. keys(): 对 键名 的遍历 。
   2. values(): 对 键值 的遍历 。
   3. entries(): 对 键值对 的遍历 。
 */

以上代码执行结果, 如图所示:

之前有整理过部分知识点, 现在将整理的相关内容, 验证之后慢慢分享给大家; 这个专题是 “前端ES6基础” 的相关专栏; 不积跬步,无以至千里, 戒焦戒躁 。

如果对大家有所帮助,可以点个关注、点个赞; 文章会持续打磨 。
有什么想要了解的前端知识, 可以在评论区留言, 会及时分享所相关内容 。

以上是关于JavaScript ES6 - 对象扩展的主要内容,如果未能解决你的问题,请参考以下文章

使用对象扩展运算符(ES6、JavaScript)添加多个对象

javascript ES6类型和对象扩展

javascript ES6 新特性之 扩展运算符 三个点 ...

JavaScript ES6 - 数组扩展

JavaScript学习笔记 -- ES6学习 变量的解构赋值

JavaScript ES6 - 这是扩展语法还是休息语法?