Skip to content

Instantly share code, notes, and snippets.

@unscriptable
Created December 6, 2011 12:58
Closure compiler is too smart for ES5 shims
// google closure compiler turns this:
function indexOf (item /*, fromIndex */) {
return find(this, item, arguments[1] /* fromIndex */, true);
}
// into this (notice the new function argument):
function q(a,c){b(this,a,c,!0)}
/*
Q: Why is this bad?
A: Because ES5 (http://es5.github.com/#x15.4.4.14) says that
the function signature for Array.prototype.indexOf must
have length == 1. For strict ES5 compliance, there cannot
be extra arguments.
*/
// How to fix it:
function indexOf (item /*, fromIndex */) {
// Notice the +1 below. Closure compiler thinks it's an equation?
return find(this, item, arguments[+1] /* fromIndex */, true);
}
@concavelenz
Copy link

Yeah, that would be this code at work:
http://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/javascript/jscomp/OptimizeArgumentsArray.java

But isn't the point of the spec that indexOf should not accept extra parameters in strict mode?

@unscriptable
Copy link
Author

Yep. That's the code! I see there are no configuration options to alter its behavior either.

But isn't the point of the spec that indexOf should not accept extra parameters in strict mode?

The intent of the spec is not to throw exceptions or otherwise limit what arguments devs can provide to indexOf. The fromIndex parameter is still allowed in strict mode. (I checked with the code below.) Instead, I think it's to provide more meaningful introspection. That's just a guess since the spec doesn't say.

this.x = 37;
(function (global) {
"use strict";
console.log(["bar","foo","bar"].indexOf("foo", global.x));
// test for strict mode. this should throw:
console.log(["bar","foo","bar"].indexOf("foo", this.x));
}(this));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment