I'm trying to understand why javascript is doing something unexpected (to me). Here's a bit of code that's purely for example. In other words, I don't actually want to extend String (I'm actually binding to functions and stuff). So this is plain javascript with no libraries.
var s = 'blah';
String.prototype.foo = function () {
console.log('this === s:', this === s);
console.log('this == s:', this == s);
console.log('typeof this:', typeof this);
console.log('typeof s:', typeof s);
console.log('this:', this);
console.log('s:', s);
};
s.foo()
And here's the output in Safari's script console:
this === s: false
this == s: true
typeof this: object
typeof s: string
this: [object Object]
s: blah
Similar output in IE, FF, Chrome, etc.
I'm trying to wrap my head around why this === s is not true. Also why this is an "object" but s is a "string".
What's going on here?
"Also why this is an "object" but s is a "string"."
It'll be easier if we start with this one.
This is because when you call a method on a primitive value, it is converted to its object wrapper for you (since that's where the methods are). This means that the this
value in the function will be the object wrapper, and not the primitive string.
It's as though you were doing this:
new String( s ).foo();
So this explains the typeof
result and the [object Object]
output.
"I'm trying to wrap my head around why this === s is not true."
This is probably more understandable now. Because this
is not a reference to the original string, but rather its object wrapper, you're not comparing identical items by any definition of ===
.
The reason ==
works is that it does type coercion. The Object wrapper is converted to a string primitive, and so you end up with an equal comparison.
You should note that if you're running your code in strict mode, and you call the method on a primitive, the value of this
will be the primitive instead of its object wrapper.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With