mathiasbynens / Array.from

A robust & optimized ES3-compatible polyfill for the `Array.from` method in ECMAScript 6.

Home Page:https://mths.be/array-from

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Compatible with IE6-8?

triblondon opened this issue · comments

I have incorporated this polyfill into the FT polyfill service, because you have some good tests and it gave me a good example to try and build a test framework around for all our polyfills. But having ported your tests to mocha/expect, they are failing in IE6-8. The whole suite passes in Chrome, Firefox and Safari.

You can run the tests in a browser here (ideally use IE 6, 7 and 8 - I'm running them using the modern.ie VMs):

http://ft-polyfill-service-qa.herokuapp.com/v1/test/tests?feature=Array.from

So my question is: is your polyfill incomplete in IE < 9, or have I made a mistake in porting the tests (or in the test framework, I suppose)?

image

In IE < 9, it's impossible to assign non-enumerable properties, so that test should fail.

I'm not sure about the "works with strings" test.

(fwiw, "does not call setters for indexes" fails in Safari 8)

Why do the tests need to be ported? tape tests run fine in the browser already, and you can add a custom HTML reporter if you need to.

Interesting, thanks. So if enumerability of the property doesn't affect its ability to polyfill the feature, maybe that should not be tested in my CI tests for the polyfill? I am using the test suite as a means of automating a process of figuring out which polyfills work in which browsers. If the tests fail, the polyfill is marked as not working for that browser.

I'd probably feature-detect if Object.defineProperty works on non-elements (in IE 8, it works on HTML elements only; in < IE 8 and ES3 browsers, it doesn't work at all), and when it doesn't work, don't bother testing for enumerability. However, in a browser where it works, I'd absolutely test for it.

A similar example: IE 6-8 have a bug with not being able to differentiate sparse arrays and arrays with undefined values, so I'd feature detect for that, and in any browser where sparse arrays work properly should absolutely run all the sparse array tests when appropriate.

The purpose of a polyfill is to normalise an API, so you can just code using one version and not worry about inconsistencies, right? If that's the case, then I would suggest that the tests should assert that it's consistent in the way that's important to you. Clearly if we're happy to use this polyfill despite the fact that the property it creates is enumerable, then the enumerability is not that important to the decision to adopt the polyfill.

So if the fact that Array.from is enumerable in some browsers is not getting in the way of it being a good polyfill, I think I should just remove that test from the test suite - or mark those tests as skipped and note that this aspect of the feature is not required to be consistent for a workable polyfill to exist.

In a browser where non-enumerability is possible, I'd say it's very important. Can you not conditionally skip those tests based on the browser's support for non-enumerability?

I just can't get past the fact that the whole point of a polyfill is to allow you to use a thing in the same manner in all browsers, so that's what we should be asserting in a polyfill's tests. Asserting that the polyfill presents a different interface in different browsers seems to counter the principle of polyfilling, doesn't it?

So my response on the enumerability thing is that from a principle perspective, I don't care if the property is enumerable in browsers where it is possible to prevent that.

I wrote up some contribution guidelines for our service based on that idea.

The danger is obviously in implementing polyfills that don't match the spec, and result in browser vendors having difficulty rolling out a native implementation. We must absolutely avoid being responsible for that, it would slow down the evolution of the web, which is the opposite of what we're trying to achieve here.

in all browsers where it is possible. You can't polyfill ES6 Maps/Sets, for example, unless you have property descriptors - thus, any ES6 Map/Set polyfill would need to feature detect for descriptors, and do nothing if they weren't supported.

The danger is that in a browser where enumerability is supported, it will surprise developers and betray their expectations to find something enumerable that shouldn't be - think Object.keys output for example. If your polyfill is betraying their expectations because it's not complying with the spec (as possible in their browser), then your polyfill is toxic to them and to the web as a whole, even if it's not toxic in the same manner as extending native prototypes arbitrarily.