所以我们在代码中都有这个垃圾,IMO太多了。例如:
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}`);
即使帐户设置为文字,我仍然会获得上面的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}`);
})();
答案 0 :(得分:4)
Lodash的_.get()
非常好,如果你想在对象profile.player.id
中嵌套一些东西,如果没有找到任何东西或者有错误,它也有一个默认值,例如这个例子{{ 1}}。
如果它是对象的直接属性,则可以使用destructuring with a default:
_.get(account, 'profileId', null);
更好的解决方案可能是stage-1 proposal-optional-chaining如果它符合规范,尽管你现在可以将它与babel插件一起使用:
const account = {};
const game = { player: 'Sam' }
const { profileId = null } = account || {};
const { player } = game || {};
console.log(profileId);
console.log(player);
答案 1 :(得分:2)
_.get
是一种辅助方法,出于多种原因使用。它可以帮助您减少代码/逻辑重复,更难以发生错误,更容易阅读和维护代码。
如果您担心_.get
和(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
和近原生性能的相同优点。您可以预先知道自己的帮助函数,知道将传递给它的数据类型,从而为您的特定用例编写零开销助手。
答案 2 :(得分:0)
这是“ 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);
}
答案 3 :(得分:0)
这是从最近的一次讨论中得出的:
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()都是不错的选择。
更新:修复缺少的正则表达式!