Así que tenemos esta basura en todo nuestro código, IMO demasiado lodash. Por ejemplo:

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

¿Soy yo o es ridículo usar lodash para todo cuando solo puedes acceder a las propiedades del objeto por el objeto! En general, estamos usando lodash y es excesivo en muchos lugares y solo hace que el código sea más detallado y difícil de leer cuando lo tienes todo.

En este caso, tampoco necesitamos lodash:

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

¿Cuál sería una manera de hacer eso sin lodash? Esa es mi pregunta Aquí hay algunos pensamientos:

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

Alguna otra idea?

ACTUALIZACIÓN

Interesante, fui con la respuesta de Ori, pero solo una observación aquí. Quería eliminar el valor predeterminado del profileId a nulo solo porque siento que no es necesario. Pero, ¿por qué esto no configuró profileId en el objeto de la cuenta?

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}`);

A pesar de que la cuenta está establecida en un literal, sigo obteniendo undefined para profileId arriba. Eso es raro..?

SOLUCIÓN FINAL (ejecute esto en codepen.io ya que necesitará cargar todo)

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}`);
})();
4
PositiveGuy 30 oct. 2017 a las 22:55

4 respuestas

La mejor respuesta

_.get() de Lodash es realmente bueno si quiere obtener algo anidado dentro de un objeto profile.player.id por ejemplo, y también tiene un valor predeterminado si no se encuentra nada o hay un error, como este ejemplo _.get(account, 'profileId', null); .

Si es una propiedad directa del objeto, puede usar Desestructuración con un valor predeterminado:

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


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

console.log(profileId);
console.log(player);

Una solución mejor podría ser la etapa-1 propuesta-opcional-encadenamiento si lo hace en la especificación, aunque puede usarlo con un complemento de babel en este momento:

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

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

const safe = obj?.qux?.baz; // undefined
4
Ori Drori 30 oct. 2017 a las 20:36

Esto surge de una discusión reciente:

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);

Pero puedes escribir una función:

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

Por supuesto es más simple de usar:

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

En general, en todos los lugares donde no sabe lo que va a reemplazar, _.get () es algo bueno.

ACTUALIZACIÓN : ¡repara la expresión regular que falta!

0
Daniele Cruciani 12 nov. 2018 a las 17:25

Aquí hay una buena frase del artículo "Acceso seguro a valores profundamente anidados en 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);
}
0
xpuu 7 nov. 2018 a las 10:14

_.get es un método auxiliar que se utiliza por varias razones. Le ayuda a reducir la duplicación de código / lógica, es más difícil cometer un error y es más fácil leer y mantener su código.

Si le preocupa la diferencia de rendimiento entre _.get y (account && account.profileId) || null, no creo que deba preocuparse a menos que tenga una enorme base de código que llame a _.get cientos de veces. Aquí está la definición de la función get de lodash y sus dependencias.

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;
}

Siempre puede realizar una prueba de referencia para su código con 2 variaciones diferentes y luego decidir si hace suficiente diferencia para que use la implementación nativa.

Acabo de hacer una prueba de referencia en la que ._get de lodash fue 95% más lento que la implementación nativa. Supongo que puede permitírselo a menos que su código se base en gran medida en ._get como se indicó anteriormente. Quizás una alternativa aún mejor sería escribir su propia función de ayuda para deshacerse de la sobrecarga de lodash y lograr los mismos beneficios de get y también el rendimiento casi nativo de lodash. Puede definir su propia función auxiliar sabiendo de antemano qué tipo de datos se le pasarán, escribiendo así un auxiliar auxiliar cero para su caso de uso específico.

2
Ante Gulin 30 oct. 2017 a las 20:20