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.
Releases 1.1.2.