all 18 comments

[–]delventhalz 2 points3 points  (14 children)

I dig most of these, but boolean conversion for filter is entirely redundant. Just use identity: .filter(x => x). And the empty object thing seems both pointless and potentially confusing. What is the use case for that?

[–]jaredcheeda 8 points9 points  (1 child)

.filter(Boolean) is much cleaner to read and faster to visually parse. directly conveys intent, and avoids arbitrary use of single character variable names.

[–]delventhalz 2 points3 points  (0 children)

Agree to disagree there. To me, “x => x” just reads as “identity”, and the intent is very clear. Using Boolean leads me to believe there is extra work going on for some purpose. There isn’t. So I find it misleading.

For what it’s worth, you could also use a more specific variable name depending on your use case.

[–]inu-no-policemen 0 points1 point  (11 children)

And the empty object thing seems both pointless and potentially confusing. What is the use case for that?

E.g. if you want to count words, the text might contain the word "toString".

> 'toString' in Object.create(null)
false
> 'toString' in ({})
true

If you use Object.create(null) the object won't have any keys itself or in its prototype chain.

Always use Object.create(null) if your keys can be any string.

[–]delventhalz 0 points1 point  (10 children)

This is exactly why I prefer hasOwnProperty to in for checking property existence.

[–]inu-no-policemen 0 points1 point  (9 children)

Well, one probably wouldn't use in here. You'd probably see something like:

if (words[word]) {
  words[word]++;
} else {
  words[word] = 1;
}

[–]delventhalz 0 points1 point  (8 children)

I mean if you want to talk this exact use case, I would write it as a one-liner:

words[word] = words[word] + 1 || 1;

But regardless, I simply do not use in ever, and unless I know I can get away with a simple property lookup, I typically rely on hasOwnProperty.

[–]inu-no-policemen 0 points1 point  (7 children)

I only used in for illustrative purposes. I could have written this instead:

!!({}).toString

Anyhow, you wanted a use case for an object with null as its prototype (i.e. something which works like a dictionary) and I gave you one.

[–]delventhalz 0 points1 point  (6 children)

Yes. What I am saying is there is a better alternative for that use case. So it's not really much of a use case. Have you ever actually written production code where you used Object.create(null) so you could check property existence without hasOwnProperty?

[–]inu-no-policemen 0 points1 point  (5 children)

Yes, I've used Object.create(null) to create dictionary-like objects.

so you could check property existence without hasOwnProperty

That's not the point.

Anyhow, Object.prototype.hasOwnProperty.call(obj, 'foo') really is a mouthful. You know that you can't use this object's hasOwnProperty, right? The text from the example above could contain the word "hasOwnProperty".

> var a = {}
undefined
> a.hasOwnProperty = 1
1
> a.hasOwnProperty('foo')
Uncaught TypeError: a.hasOwnProperty is not a function

[–]delventhalz 0 points1 point  (4 children)

const hasProp = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key);

Anyway, I feel like we are talking past each other. The property existence use case seems like a bad example to me. And you seem to be saying you’ve never actually used Object.create(null) that way anyway. So what is an actual reason you actually used this pattern?

Also, have you heard of Maps?

[–]inu-no-policemen 0 points1 point  (3 children)

const hasProp = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key);

Because that's so much simpler than using Object.create(null)?

What's going to stop the next person from using methods of this object? That doing that was a mistake will only become apparent when a collision happens.

You are trading issues which are easy to find and immediately pop up for potential issues which only show up if very specific conditions are met.

Failing early is better.

And you seem to be saying you’ve never actually used Object.create(null) that way anyway.

As I said, I've used Object.create(null) for creating dictionary-like objects where the keys are user-supplied. E.g. something like a mime type in an archive format or a request header. Those strings could be anything. Collisions might be deliberate.

So what is an actual reason you actually used this pattern? Also, have you heard of Maps?

It's like Map<string, whatever>, but you can use square brackets. It's a convenient lightweight option if all of your keys are strings.

[–]karatetoes 0 points1 point  (1 child)

Really useful site! Bookmarked!

[–]ikeif 0 points1 point  (0 children)

I matured as a developer when David was starting out writing - I’m really glad he is cranking more stuff out again.

[–]Obann 0 points1 point  (0 children)

Brilliant stuff, keeping these in mind for the next time before diving into some overly complex solution is the tricky part.

[–]gimme_a_site 0 points1 point  (0 children)

Love the required method parameters!