ES6常用對象操作整理


const

簡單類型數據常量

// const實際上保證的,並不是變量的值不得改動,而是變量指向的那個內存地址不得改動。對於簡單類型的數據(數值、字符串、布爾值),值就保存在變量指向的那個內存地址,因此等同於常量。 
const PI = 3.1415926; 
console.log(PI)

 

對象常量

const foo = Object.freeze({});

// 常規模式時,下面一行不起作用;
// 嚴格模式時,該行會報錯
foo.prop = 123;

 

除了將對象本身凍結,對象的屬性也應該凍結。下面是一個將對象徹底凍結的函數。

var constantize = (obj) => {
  Object.freeze(obj);
  Object.keys(obj).forEach( (key, i) => {
    if ( typeof obj[key] === 'object' ) {
      constantize( obj[key] );
    }
  });
};

 

屬性的簡潔表示

對象,函數都可以簡寫

var birth = '2000/01/01';
var Person = {
  name: '張三',
  //等同於birth: birth
  birth,
  // 等同於hello: function ()...
  hello() { console.log('我的名字是', this.name); }
};

 

CommonJS模塊輸出變量,就非常合適使用簡潔寫法。

var ms = {};

function getItem(key) {
  return key in ms ? ms[key] : null;
}

function setItem(key, value) {
  ms[key] = value;
}

function clear() {
  ms = {};
}

module.exports = {
  getItem,
  setItem,
  clear
};
// 等同於
module.exports = {
  getItem: getItem,
  setItem: setItem,
  clear: clear
};

 

Object.is()

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

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

 

Object.assign()

用於對象的合並,如果目標對象與源對象有同名屬性,或多個源對象有同名屬性,則后面的屬性會覆蓋前面的屬性。

var target = { a: 1 };

var source1 = { b: 2 };
var source2 = { c: 3 };

Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}

 

注意點:

Object.assign 方法實行的是淺拷貝

var obj1 = {a: {b: 1}};
var obj2 = Object.assign({}, obj1);

obj1.a.b = 2;
obj2.a.b // 2

 

常見用途:

(1)為對象添加屬性

class Point {
  constructor(x, y) {
    Object.assign(this, {x, y});
  }
}

 

(2)為對象添加方法

Object.assign(SomeClass.prototype, {
  someMethod(arg1, arg2) {
    ···
  },
  anotherMethod() {
    ···
  }
});

// 等同於下面的寫法
SomeClass.prototype.someMethod = function (arg1, arg2) {
  ···
};
SomeClass.prototype.anotherMethod = function () {
  ···
};

 

(3)克隆對象

function clone(origin) {
  return Object.assign({}, origin);
}

不過,采用這種方法克隆,只能克隆原始對象自身的值,不能克隆它繼承的值。

想要保持繼承鏈,可以采用下面的代碼。

function clone(origin) {
  let originProto = Object.getPrototypeOf(origin);
  return Object.assign(Object.create(originProto), origin);
}

 

(4)合並多個對象

const merge =
  (target, ...sources) => Object.assign(target, ...sources);
const merge =
  (...sources) => Object.assign({}, ...sources);

 

(5)為屬性指定默認值

const DEFAULTS = {
  logLevel: 0,
  outputFormat: 'html'
};

function processContent(options) {
  options = Object.assign({}, DEFAULTS, options);
  console.log(options);
  // ...
}

由於存在深拷貝的問題,DEFAULTS對象和options對象的所有屬性的值,最好都是簡單類型,不要指向另一個對象。

 

屬性的遍歷

ES6一共有5種方法可以遍歷對象的屬性。

(1)for...in

for...in循環遍歷對象自身的和繼承的可枚舉屬性(不含Symbol屬性)。

(2)Object.keys(obj)

Object.keys返回一個數組,包括對象自身的(不含繼承的)所有可枚舉屬性(不含Symbol屬性)。

(3)Object.getOwnPropertyNames(obj)

Object.getOwnPropertyNames返回一個數組,包含對象自身的所有屬性(不含Symbol屬性,但是包括不可枚舉屬性)。

(4)Object.getOwnPropertySymbols(obj)

Object.getOwnPropertySymbols返回一個數組,包含對象自身的所有Symbol屬性。

(5)Reflect.ownKeys(obj)

Reflect.ownKeys返回一個數組,包含對象自身的所有屬性,不管是屬性名是Symbol或字符串,也不管是否可枚舉。

(對象自身屬性遍歷):

for (var i in data) {
  if (data.hasOwnProperty(i) === true) {
    console.log(data[i])
  }
}

 

 

Object.keys(),Object.values(),Object.entries()

ES5 引入了Object.keys方法,返回一個數組,成員是參數對象自身的(不含繼承的)所有可遍歷(enumerable)屬性的鍵名。

var obj = { foo: 'bar', baz: 42 };
Object.keys(obj)
// ["foo", "baz"]

ES2017 引入了跟Object.keys配套的Object.values和Object.entries,作為遍歷一個對象的補充手段,供for...of循環使用。

var obj = { foo: 'bar', baz: 42 };
Object.values(obj)
// ["bar", 42]

 

對象的擴展運算符

(1)解構賦值

let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
x // 1
y // 2
z // { a: 3, b: 4 }

(2)擴展運算符

let z = { a: 3, b: 4 };
let n = { ...z };
n // { a: 3, b: 4 }

 

Null 傳導運算符

編程實務中,如果讀取對象內部的某個屬性,往往需要判斷一下該對象是否存在。比如,要讀取message.body.user.firstName,安全的寫法是寫成下面這樣。

const firstName = (message
  && message.body
  && message.body.user
  && message.body.user.firstName) || 'default';

這樣的層層判斷非常麻煩,因此現在有一個提案,引入了“Null 傳導運算符”(null propagation operator)?.,簡化上面的寫法。

const firstName = message?.body?.user?.firstName || 'default';

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM