Feel free to skip the first paragraph if you’ve read my previous restrict mode articles.
I’ve tweaked the restrict mode semantics somewhat since then:
I removed the restrict mode custom versions of
!=. This shouldn’t come as a big surprise since I hinted that I wasn’t happy with clause 1 in the case for restrict mode. Now all of
!== behave identically in normal and restrict mode and you should strongly consider not using
!= irrespective of whether you use restrict mode or not.
I relaxed the restrict mode
+ operator slightly. It was previously only allowed for
str + str (concatenation) or
num + num (addition), but never a mix. It’s now also allowed for
num + str or
str + num, which happens to be the most common coercing usage of it out there in the wild. I hope that this will lower the barrier of restrict mode adoption.
Back to jQuery. I cloned the jQuery repo, ran it through
restricter (with restrict mode forced no matter
"use restrict"; directives) and fixed the restrict mode run-time errors until all tests passed again.
restricter ran on everything under
src/ excluding the Sizzle dependency, to be precise. It should be easy to try it on Sizzle as well, or on something else for that matter.
The required changes to get jQuery restrict mode clean were few and small. They can be partitioned into three classes:
Most were about fixing the
str + nostr_nonum antipattern
str < num
str + undefined
String(expr). The patched version may be a bit easier to reason about and slightly more robust to future changes, especially so for newcomers to the jQuery codebase. Being explicit makes it slightly more verbose.
The class 3 change is more interesting.
str + undefined is rarely done on purpose.
jQuery.fn.hasClass should guard against missing className properties but doesn’t, and as a consequence
element.hasClass("undefined") may return
true when it shouldn’t. An easy way to demonstrate this is to change
test/unit/attributes.js, line 860. Change
Seems like restrict mode found us a jQuery bug.
Follow me on Twitter