elado / lodash-bound

Enables chained lodash functions with ES bind (::) syntax

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

isUndefined always returns false

mhelvens opened this issue · comments

Hi, Thanks for a useful library!

There's a problem with 'lodash-bound/isUndefined'. It always returns false. Other similar functions, like 'isNumber' work fine:

https://tonicdev.com/579e050049cba51300e9aedd/579e050049cba51300e9aede

I'm not sure why. I guess undefined is a special case.

Good point. Apparently fn.call(undefined) doesn't pass undefined as an argument, and this remains global (or window in a browser).

http://jsbin.com/fimahal/edit?js,console

function f() {
  console.log(Object.prototype.toString.call(this))
  return this
}

const call1 = f.call(1)
console.log(call1 == 1)

const callUndefined = f.call(undefined)
if (callUndefined === window) {
  console.log('fail - callUndefined returned window')
}
else if (callUndefined === undefined) {
  console.log('success - callUndefined returned undefined')
}

Tricky one. I could compare this to global and if so, to use undefined, but what happens if global is intentionally sent to a method?

Another thing I just found out is that the JS engine wraps primitives. 1 becomes new Number(1) when accessing this. So === comparison returns false.

Keeping this open until I find or suggested a better solution. I'm leaning towards treating global as undefined. But it's definitely a gotcha.

It's a tricky choice, indeed. People might well try global::isUndefined() to test whether they're in a browser.

I would propose that, if someone imports lodash-bound/isUndefined, you print an error to the console to explain the situation. Also provide two working versions: lodash-bound/isUndefined-no-error-node and lodash-bound/isUndefined-no-error-browser, and make both behave accordingly.

As for primitives being wrapped in an object, good point. Some of the other methods will misbehave too, like isObject:

https://tonicdev.com/579e050049cba51300e9aedd/57a0ae8d79342e13001cc6b6

For those, I'd propose a similar solution. If they are imported directly, print a warning to the console. Also provide a clean version lodash-bound/isObject-no-warning that doesn't print the warning. Importing that specific file indicates that the developer is aware of the limitations.

All of this in addition to good documentation, of course.

Use the "use strict" directive in lodash-bound/scripts/method.ejs to allow a this binding of undefined.
Our _.isNumber method works for number primitives and objects.

@jdalton Nice, an actual real solution!

And strict mode solves the other problem too. Binding a primitive value won't wrap it in an object. :-)

So this should be a very simple fix.

Yep, on it! Thanks @jdalton and @mhelvens for reporting.

Releases 1.1.2.