簡體   English   中英

比使用 Lodash 更好的獲取屬性的方法

[英]Better way to Get Property Than using Lodash

所以我們的代碼中到處都是這些廢話,IMO 太多 lodash。 例如:

const profileId = _.get(account, 'profileId', null);
const player = _.get(someCustomObject, 'player'); // Why??????  why not just someCustomObject.player?

當您只能通過對象訪問對象屬性時,是我還是將 lodash 用於所有內容是荒謬的! 總的來說,我們使用 lodash,它在很多地方都是過大的,只是讓代碼變得更加冗長和難以閱讀。

在這種情況下,我們也不需要 lodash:

const profileId = _.get(account, 'profileId', null);

沒有 lodash 有什么方法可以做到這一點? 這是我的問題。 這里有一些想法:

const profileId = (account && account.profileId) || null

還有其他想法嗎?

更新

有趣的是,按照 Ori 的回答,但只是在這里觀察。 我想刪除默認的 profileId 為 null 只是因為我覺得這是不必要的。 但是為什么這沒有將 profileId 設置為帳戶對象?

 const account = {}; const game = { player: 'Sam' } console.log(`account: ${account}`); const { profileId } = account || {}; const { player } = game || {}; console.log(`profileId: ${profileId} // why is this undefined if account has value {}???`); console.log(`player: ${player}`);

即使 account 設置為文字,我仍然undefined為上面的 profileId undefined 這很奇怪。。?

最終解決方案(在codepen.io 中運行它,因為你需要加載 lodash)

console.log(" Example Clean Code without Lodash")
console.log('===============================')

let account = {};
const game = { player: 'Sam' }

console.log(`account: ${account}`);

const { profileId = null } = account;
const { player } = game || {};

console.log(`profileId: ${profileId}`);
console.log(`player: ${player}`);

/* using IIFE so profileId doesn't conflict with example above */
(() => {
  console.log("Example using unecessary Lodash")
  console.log('===============================')

  let profileId = _.get(account, 'profileId', null);
  const game = { player: 'Sam' } 

  console.log(`account2: ${account}`);

  const { player } = game || {};

  console.log(`profileId: ${profileId}`);
  console.log(`player: ${player}`);
})();

Lodash 的_.get()非常好,如果你想在對象profile.player.id嵌套一些東西,例如,如果沒有找到任何東西或有錯誤,它也有一個默認值,就像這個例子_.get(account, 'profileId', null); .

如果它是對象的直接屬性,則可以使用具有默認值的解構

 const account = {}; const game = { player: 'Sam' } const { profileId = null } = account || {}; const { player } = game || {}; console.log(profileId); console.log(player);

一個更好的解決方案可能是 stage-1 proposal-optional-chaining如果它進入規范,盡管你現在可以將它與 babel 插件一起使用:

const obj = {
  foo: {
    bar: {
      baz: 42,
    },
  },
};

const baz = obj?.foo?.bar?.baz; // 42

const safe = obj?.qux?.baz; // undefined

_.get是一種輔助方法,用於多種原因。 它可以幫助您減少代碼/邏輯重復,更難出錯並且更容易閱讀和維護您的代碼。

如果您擔心_.get(account && account.profileId) || null之間的性能差異 (account && account.profileId) || null ,我不認為你應該擔心,除非你有一個巨大的代碼庫調用_.get次。 這是 lodash 的get函數定義及其依賴項。

function get(object, path, defaultValue) {
  var result = object == null ? undefined : baseGet(object, path);
  return result === undefined ? defaultValue : result;
}

function baseGet(object, path) {
  path = castPath(path, object);

  var index = 0,
      length = path.length;

  while (object != null && index < length) {
    object = object[toKey(path[index++])];
  }
  return (index && index == length) ? object : undefined;
}

function castPath(value, object) {
  if (isArray(value)) {
    return value;
  }
  return isKey(value, object) ? [value] : stringToPath(toString(value));
}

function toKey(value) {
  if (typeof value == 'string' || isSymbol(value)) {
    return value;
  }
  var result = (value + '');
  return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
}

您始終可以使用 2 個不同的變體對您的代碼執行基准測試,然后確定它是否對您使用本機實現有足夠的影響。

我剛剛做了一個基准測試,其中 lodash 的._get比本地實現慢95% 我想你可以負擔得起,除非你的代碼嚴重依賴._get如上所述。 也許更好的替代方法是寫自己的輔助函數來擺脫lodash的開銷,實現lodash的相同利弊get和也接近本機的性能。 您可以定義自己的輔助函數,提前知道將傳遞給它的數據類型,從而為您的特定用例編寫零開銷的輔助函數。

這是文章“ Safely Accessing Deeply Nested Values In JavaScript ”中的一個很好的單行代碼

export function _get(object, path, defval = null) {
    if (typeof path === "string") path = path.split(".");
    return path.reduce((xs, x) => (xs && xs[x] ? xs[x] : defval), object);
}

您也可以使用這個很棒的零依賴實用程序庫https://github.com/angus-c/just

這來自最近的討論:

var template = "string with {obj.prop} first of 0: {results[0].first}";
var data = {obj: {prop: 'mine'}, results:[{first:'f'},{first:'ff'}] }
var regex = /{(.*?)}/g;
var str = template.replace(regex, (e, key) => _.get(data, key, ''));
console.log(str);

但是你可以寫一個函數:

const interpolate = (template, data) => template.replace(/{(.*?)}/g, (e, key) => _.get(data, key, ''));

當然使用起來更簡單:

let str = interpolate("string with {obj.prop} first of 0: {results[0].first}", data)

一般來說,在你不知道要替換什么的地方, _.get() 是個好東西。

更新:修復丟失的正則表達式!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM