更简洁的语法

定义属性

我们都知道定义一个对象,必须明确属性名和对应的值,及时属性名和声明的变量名一样(var a = {obj:obj}),ES6及后续版本允许我们用短的代码声明对象,用于将对象的属性分配给与属性同名的变量,我们一般会这么声明变量,代码如下:

  1. var x = 1, y = 2;
  2. var object = {
  3. x: x,
  4. y: y
  5. };
  6. console.log(object.x); //output "1”复制代码

但是ES6之后,你可以这么做

  1. let x = 1, y = 2;
  2. let object = { x, y };
  3. console.log(object.x); 复制代码

定义方法

ES6提供了一种新的语法定义对象的方法,示例代码如下:

  1. let object = {
  2. myFunction(){
  3. console.log("Hello World!!!"); //Output "Hello World!!!"
  4. }
  5. }
  6. object.myFunction();复制代码

我们可以看出,省去了声明属性名,属性名即为方法名。

计算属性名

对象属性支持计算属性名。其允许在[]中放入表达式,计算结果可以当做属性名。

  1. let object = {
  2. ["first" + "Name"]: "Eden",
  3. };
  4. //extract
  5. console.log(object["first" + "Name"]);
  6. //Output "Eden”
  7. console.log(object);
  8. //Output "{ firstName: 'Eden' }”复制代码

Object.values()

ES8 引入了Object.values()方法,以数组的形式输出所有对象的值,省去我们手动迭代取出每个对象属性的值,示例代码如下:

  1. const obj = {
  2. book: "Learning ES2017 (ES8)",
  3. author: "前端达人",
  4. publisher: "前端达人",
  5. useful: true
  6. };
  7. console.log(Object.values(obj));复制代码

上述代码将会输出:

  1. [ 'Learning ES2017 (ES8)', '前端达人', '前端达人', true ]复制代码

Object.entries()

Object.entries()可用于将对象转换为键/值对的数组形式。 即一个二维数组,数组的每个元素是一个包含键和值的数组。 示例代码如下:

  1. const obj = {
  2. book: "Learning ES2017 (ES8)",
  3. author: "前端达人",
  4. publisher: "前端达人",
  5. useful: true
  6. };
  7. console.log(Object.entries(obj));复制代码

上述代码将会输出:

  1. [ [ 'book', 'Learning ES2017 (ES8)' ],
  2. [ 'author', '前端达人' ],
  3. [ 'publisher', '前端达人' ],
  4. [ 'useful', true ] ]复制代码

proto

proto:是一个对象拥有的内置属性,是JS内部使用寻找原型链的属性。可以理解为它是一个指针,用于指向创建它的函数对象的原型对象prototype(即构造函数的prototype)。prototype(原型对象):是函数(Function)的一个属性(每个函数都有一个prototype),这个对象包含了此函数的所有实例共享的属性和方法,即:原型对象。
proto属性在ES5中没有标准化,但由于它的受欢迎程度,它在以后的版本中被标准化了。 我们可以使用Object.getPrototypeOf()方法返回指定对象的原型(内部[[Prototype]]属性的值,可以使用Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的proto

  1. //In ES5
  2. var x = {prop1: 12};
  3. var y = Object.create(x, {prop2:{value: 13}});
  4. console.log(y.prop1); //Output "12"
  5. console.log(y.prop2); //Output "13"
  6. console.log(x); // Output: {prop1: 12}
  7. console.log(y); // Output: {prop2: 13}
  8. console.log(y.__proto__); // Output: {prop1: 12}
  9. //In ES6 onwards
  10. let a = {prop1: 12, __proto__: {prop2: 13}};
  11. console.log(a.prop1); //Output "12"
  12. console.log(a.prop2); //Output "13"
  13. console.log(a); // Output: {prop1: 12}
  14. console.log(a.__proto__); // Output: {prop2: 13}复制代码

在ES5示例中,对象y继承对象x,x的属性相对于y来说是隐藏的,我们可以使用proto来查找继承自x的属性prop1。ES6及其后,你可以直接将值添加到对象的原型链中。

Object.is()

Object.is()方法用于确定两个值是否相等。它类似于===运算符,但Object.is()方法有一些特殊情况和使用“===”的结果是不一致的,如下段代码所示:

  1. console.log(Object.is(0, -0));//false
  2. console.log(0 === -0);//true
  3. console.log(Object.is(NaN, 0/0));//true
  4. console.log(NaN === 0/0);//false
  5. console.log(Object.is(NaN, NaN));//true
  6. console.log(NaN ===NaN);//false复制代码

如下图所示,展示了使用==,===和Object.is的结果差异:

Object.setPrototypeOf()

Object.setPrototypeOf方法可以为现有对象设置原型,返回一个新对象。Object.setPrototypeOf方法接受两个参数,第一个是现有对象,第二个是原型对象。Object.setPrototypeOf() 是给对象设置原型,是为了obj.proto = …. 这种写法更优雅,有更好的兼容性。如下段代码所示:

  1. let x = {x: 12};
  2. let y = {y: 13};
  3. Object.setPrototypeOf(y, x);
  4. console.log(y.x); //Output "12"
  5. console.log(y.y); //Output "13”
  6. console.log(y);//Output "{ y: 13 }"
  7. console.log(y.__proto__);//Output "{ x: 12 }"复制代码

Object.assign()

Object.assign()方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。它至少需要两个对象作为参数,第一个参数是目标对象,后面的参数都是源对象。如下段代码所示:

  1. let x = {x: 12};
  2. let y = {y: 13, __proto__: x};
  3. let z = {z: 14, get b() {return 2;}, q: {}};
  4. Object.defineProperty(z, "z", {enumerable: false});
  5. let m = {};
  6. Object.assign(m, y, z);
  7. console.log(m.y);//13
  8. console.log(m.z);//undefined
  9. console.log(m.b);//2
  10. console.log(m.x);//undefined
  11. console.log(m.q == z.q);//true复制代码

从上述代码输出,我们可以得出Object.assign()方法的一些特征:

  • 该方法使用源对象的[[Get]]和目标对象的[[Set]],所以它会调用相关getter和setter。
  • 它只是将源的属性值分配给目标的新属性或现有属性。
  • 它不会复制来源的[[prototype]]属性。
  • JavaScript属性名称可以是字符串或symbol。Object.assign()这两种都支持。
  • Object.assign方法只会拷贝源对象自身的并且可枚举的属性到目标对象。
  • 如果目标对象中的属性具有相同的键,则属性将被源中的属性覆盖。后来的源的属性将覆盖早先的属性。
  • 为了将属性定义(包括其可枚举性)复制到原型,应使用Object.getOwnPropertyDescriptor()和Object.defineProperty() 。
  • Object.assign不会跳过那些值为[null]或[undefined]的源对象。

    Object.getOwnPropertyDescriptors()

    在ES8中JS引入Object.getOwnPropertyDescriptors()方法将返回给定对象的所有属性描述,如下段代码所示:
    1. const details = {
    2. get food1() { return 'tasty'; },
    3. get food2() { return 'bad'; }
    4. };
    5. console.log(Object.getOwnPropertyDescriptors(details));复制代码
    上述代码将会输出:
    1. { food1:
    2. { get: [Function: get food1],
    3. set: undefined,
    4. enumerable: true,
    5. configurable: true },
    6. food2:
    7. { get: [Function: get food2],
    8. set: undefined,
    9. enumerable: true,
    10. configurable: true } }复制代码
    这个方法还会用在对象的克隆上,示例代码如下:
    1. const x = { foo: 1, __proto__: { bar: 2 } };
    2. const y = Object.create(
    3. Object.getPrototypeOf(x),
    4. Object.getOwnPropertyDescriptors(x)
    5. );
    6. console.log(y.__proto__); // { bar: 2 }

作者:前端达人
链接:https://juejin.im/post/5cec9a58f265da1bc94ecdce
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。