Not necessarily -- it's because the indexOf()
native function uses the direct this
value passed, not the one converted to an object (equivalent to what happens in strict mode), and such a shim would need to check for this to be compliant. For example, this code will throw a TypeError
:
var a = Array.prototype.indexOf;
a();
It will throw a TypeError
, as the this
value is not converted into an object or changed to the global object. In user-defined non-strict functions, the value of this
is the global object if there is no parent object, but in ES5 strict mode it is passed as undefined
itself. Another situation is when you call it specifically with either null
or undefined
:
"use strict";
Array.prototype.indexOf.call(null); // TypeError, what else can we do?
In the ES5 specification, the this value refers to the original value passed as the thisArg
, without any changes. In non-strict mode, the this value is not accessible to code in user-defined functions, but native functions are able to explicitly specify use of the this value instead of what the this
keyword evaluates to (which is referred to as the ThisBinding
in the specification). In strict mode, they both evaluate to the same thing.
Because the native version is able to access the non-boxed version of the this
value in non-strict mode (which is directly passed to the internal function [[ToObject]]
, which throws a TypeError
upon attempting to convert null
or undefined
), this check needs to implemented to satisfy the requirements of the specification.
Note: technically, the code sample in your question isn't quite by the ES5 specification, as the this
value could be falsy, which would fail it even though it should proceed in theory (native implementations of indexOf()
do not throw if false
is passed as the this
value). As well, since the global object would be passed if the this value was actually undefined or null, it would pass the if (!this)
test, even when it's not supposed to. This cannot be solved simply by checking that the argument is not the global object, because this would fail if the global object was explicitly passed (which is permitted).