.fill is not defined in IE
wikiwong opened this issue · comments
Hi just FYI, a54dc0f#diff-480465dfe1db7da61cf594d184bfe7b4R26
.fill
is not defined in IE, throwing a JS error. It may need a polyfill
It's generally bad practice to alter an array's length manually (as this lib does with version.length = 3
).
Is there any case in which the following wouldn't work?
if (version.length < 3) {
Array.prototype.push.apply(version, (version.length == 1) ? [0, 0] : [0]);
}
Fixed with: #27
Until it's merged you can install with:
$ npm i --save DamonOehlman/detect-browser#pull/27/head
Thanks @adamellsworth .
I think the original logic is a bit confusing.
if (version.length < 3) {
version.length = 3;
version.fill(0, 2);
}
The .fill
function will fill in 0s from the 2nd index of the array, which works if the array is of length 2, but if it's of length 1, the 2nd element in the array will be undefined.
@adamellsworth I think your PR makes sense, but it assumes that versions
is not an empty array (which may be a valid assumption, I'm not sure). If it is an empty array, versions
will be [0]
, and not the intended 3 item array.
From your PR:
Array.prototype.push.apply(version, (version.length == 1) ? [0, 0] : [0]);
If we know versions
will never be empty, or it doesn't really matter if it's a 3 item array, this is perfectly fine. If not, I think we need a bit more logic. Here's a crude example of filling an array recursively in a cross browser manner:
function fillTo(theArray, capacity, content) {
if (theArray.length === capacity) {
return theArray;
}
theArray.push(content);
return fillTo(theArray, capacity, content);
}
var version = [1];
fillTo(version, 3, 0);
// outputs [1, 0, 0]
Bringing in @baribadamshin as his PR introduced the .fill
logic. I'm sure there is a way we can achieve something similar without the fill (using .concat
or plain old .push
for example). I definitely think @baribadamshin's PR moved things in the right direction, we should be able to iron this one out pretty quickly.
I'll try to keep monitoring this issue so we can get it resolved quickly. On holidays at the moment so might be a bit more async than normal.
What about in that particular case we should revert to the original logic of:
while (version && version.length < 3) {
version.push(0);
}
NB: The only reason the (version && ...)
check is required is if I ever to do decide to use flow (https://flowtype.org) for this package that will be required to ensure everything typechecks.
Thoughts?
I think cycle or recursion it's overhead.
How about this?
version.concat([0, 0]).slice(0, 3)
if we have 1 element in version, we just fill empty numbers, in other case we cut excess.
[1] -> [1, 0, 0]
[1, 0] -> [1, 0, 0]
https://jsperf.com/fill-alternate-tests-2
Not sure if I'm setting these up correctly, but if so the push.apply is the quickest alternative.
That being said, @DamonOehlman is right in that it may be undefined/null.
if (version && version.length < 3) { //...
// Also, it's pretty safe to utilize 'isArray' (ecma5) if preferred
if (version && Array.isArray(version) && version.length < 3) { //...
Edit: PR Updated
Cool, folks thanks for the update. Apologies for being offline for a bit. I'm going to merge this and publish the update as 1.6.1
(removing the package.json
update) and manually update using the npm version
command which I tend to find is the best approach for this kind of thing, just prior to a publish :)
@adamellsworth Actually I'm not sure I can do that (or it feels to impolite), I'll just merge it in as is - thanks.
Merged and published as 1.6.2
.