csquared/node-logfmt

Use for-in instead of Object.keys when serializing

moll opened this issue · 7 comments

moll commented

Hey,

Object.keys has this peculiar property that it iterates only over own properties. I'd say that's an unnecessary limitations in the serializer given the power of prototypical inheritance.

Interesting. I think its desired b.c I wouldn't want to iterate over the functions of an object, just the properties that are objects themselves. Can you give me an example where Object.keys doesn't work but for-in would?

moll commented

Unfortunately or not, Object.keys does not skip function properties. For that you always need an explicit typeof test.

As I said, Object.keys does not take inherited properties into account. Inheritance is not at all limited to functions. The following idiom is not that rare and is extremely useful for default properties:

var defaults = {foo: 42, bar: "abc"}
var options = Object.create(defaults)
options.foo = 13

When you give that object to logfmt, it'll fail to include bar.

Cheers

@moll - not 100% sure what you're describing is true.

I tried your example:

var defaults = {foo: 42, bar: "abc"}
undefined
var options = Object.create(defaults)
undefined
options.foo = 13
13
var logfmt = require('logfmt')
undefined
logfmt.log(options)
foo=13
undefined
options
{ foo: 13 }

Besides that example, it appears Object.keys works fine with properties added to the object after the fact:

var data = {}
undefined
data.foo = 13
13
logfmt.log(data)
foo=13
Object.keys(data)
[ 'foo' ]

I added a test for this anyways:
7233f62

moll commented

Hey again. Oh, the problem is precisely that bar is not included.
When you for in loop over that object, both foo and bar turn up.

Ah, now I get it!

Fixed in:
00a628f

Make sure to check out the test :)

moll commented

Nice. :) I guess you may now close this issue whenever you deem suitable.

For a moment I thought you perhaps started using Must.js for assertions and that's why hinted that I check the test out. :D