var p = "null"
var q = null;
(p == q) //false. as Expected.
p.replace(null, "replaced") // outputs replaced. Not expected.
p.replace("null", "replaced") //outputs replaced. Expected.
q.replace(null, "replaced") // error. Expected.
q.replace("null", "replaced") //error. Expected.
Why? Does replace not differentiate between "null"
and null
?
I ask because I ran into a bug in angularjs:
replace((pctEncodeSpaces ? null : /%20/g), '+');
If for example, someone had a username of "null"
and it was used as url, it would be replaced with "+" on any $http
calls. e.g. GET /user/null
.
Not that this scenario would occur often, but I'm more curious why replace treats null
and "null"
as the same thing. Does replace do a .tostring on null
before it does the replacement? Is this just a quirk of Javascript?
I verified this on both IE and Chrome's implementations of replace
.
var p = "null"
var q = null;
(p == q) //false. as Expected.
p.replace(null, "replaced") // outputs replaced. Not expected.
p.replace("null", "replaced") //outputs replaced. Expected.
q.replace(null, "replaced") // error. Expected.
q.replace("null", "replaced") //error. Expected.
Why? Does replace not differentiate between "null"
and null
?
I ask because I ran into a bug in angularjs:
replace((pctEncodeSpaces ? null : /%20/g), '+');
If for example, someone had a username of "null"
and it was used as url, it would be replaced with "+" on any $http
calls. e.g. GET /user/null
.
Not that this scenario would occur often, but I'm more curious why replace treats null
and "null"
as the same thing. Does replace do a .tostring on null
before it does the replacement? Is this just a quirk of Javascript?
I verified this on both IE and Chrome's implementations of replace
.
- replace is a method of String and, as such, can only be called on strings. – nullability Commented Apr 30, 2013 at 15:50
- Sorry, maybe I should remove the q part. That's not what I'm asking about, I realize I should get that error. – petebowden Commented Apr 30, 2013 at 15:51
-
@Rastapopulous yes, that would make the question clearer. The
q
part is just distracting. – Alnitak Commented Apr 30, 2013 at 16:04
4 Answers
Reset to default 5Yes, this is expected according to the spec for replace
(bolded relevant line, or page 146 of the ECMA-262 final draft). The first argument is checked to see if it is a regex and if not, it has toString()
called on it (well, converted to a string somehow).
15.5.4.11
String.prototype.replace(searchValue, replaceValue)
Let string denote the result of converting the this value to a string.
Cut for brevity
If
searchValue
is not a regular expression, letsearchString
beToString(searchValue)
and search string for the first occurrence ofsearchString
. Let m be 0.Cut for brevity
In the ES5 specification for String.prototype.replace
:
15.5.4.11 String.prototype.replace (searchValue, replaceValue)
...
If
searchValue
is not a regular expression, letsearchString
beToString(searchValue)
and searchstring
for the first occurrence ofsearchString
So, "".replace(null, XXX)
will indeed convert the null
to the string "null"
Note that ToString()
does not mean null.toString()
- it's an internal defined operation within the JavaScript interpreter.
For the not expected one, there's a simple answer. The null is casted to string by the replace() method.
So that is also an expected action
"null".replace(null, "replaced") // outputs replaced. Not expected.
Does replace not differentiate between "null" and null
This is because parameter 1 of replace
is converted to String.
''+null === "null"; // true by cast to string
Furthermore, as replace
takes RegExp objects, you can also think about how
RegExp(null).toString() === "/null/"; // true