tags:

views:

129

answers:

2

I'm trying to write a prototype for determining if a string is empty. It's really just playing with JS and prototype, nothing important. Here's my code:

String.prototype.IsEmpty = function() {
  return (this === "");
}

Notice I used the === identity comparison instead of == equality. When I run the function with the above definition:

"".IsEmpty(); // false

If I chagne the definition to use == as:

String.prototype.IsEmpty = function() {
  return (this == "");
}

The new def'n will do:

"".IsEmpty(); // true

I don't understand why === doesn't work since "" is identical to ""

+6  A: 

=== is identity (same object; x is x**). == is equality (same value; x looks like y).

Lets play some (Rhino / JS 1.8):

{} === {} // false
new String("") === new String("") // false
typeof new String("") // object

"" === "" // true
typeof "" // string
f = function () { return "f" };
"foo" === f() + "oo" // true

String.prototype.foo = function () { return this; };
typeof "hello".foo() // object -- uh, oh! it was lifted

So, what just happened?

The difference between a String object and string. Of course, the equality compare (or .length) should be used.

The proof in the pudding, section 11.9.6 discusses the === operator algorithm

pst
Would also add that 0, false, "", null and sometimes undefined match with equality operations, which can cause some head scratching.
Tracker1
+6  A: 

It's because "" is a string primitive, but when you call .IsEmpty() it's implicitly converted to a String object.

You'd need to call .toString() on it:

String.prototype.IsEmpty = function() {
  return (this.toString() === "");
}

Interestingly this is browser-specific - typeof this is string in Chrome.

As @pst points out, if you were to convert the other way and compare this === new String(""); it still wouldn't work, as they're different instances.

Greg
I was just thinking about that -- String vs. string. Thanks for the fix.
Mark Ursino