I discovered a peculiarity in JavaScript (or perhaps my browser's idea of it):
var s = "Hello, world";
function foo(arg)
{
console.log(arg);
console.log(this);
}
foo.call(s, s);
Running the above with Firebug console enabled, I get:
Hello, world
String { 0="H", 1="e", more...}
Why does the string automatically get turned into a weird object before becoming the this passed to foo ?
The reason I call it a weird object is because jQuery chokes on it. For example:
$.each(["one", "two", "three"], function(i, x) {
$('<p></p>').text(x) .appendTo('body'); // Works
$('<p></p>').text(this).appendTo('body'); // Doesn't work
});
this is coerced into an object, i.e. Object("test") is internally called.
(function() {
return this;
}).call("test");
// returns same as `new String("test")` or `Object("test")`
if the method is a function in non-strict mode ... primitive values will be boxed*.
Note that using strict mode indeed does return the primitive value:
(function() {
"use strict";
return this;
}).call("test") === "test"; // true
* Boxing a value of a value allocates an object instance and copies the value into the new object.
When using foo.call(s1, s2), you're invoking function foo, and setting the this keyword to s1. Since this has to be an object (so, not a primitive value), it's converted to a String object.
The individual characters of a string (created through s = "..." or s = String("...")) can be accessed through indexes, hence
String { 0="H", 1="e", more...}
function foo(arg)
{
console.log(arg); // passed as "Hello, world"
console.log(this); // passed as String("Hello, world")
console.log(this instanceof String); //True
}
var i=0, s = "Hello, world";
for(; i<s.length; i++){
console.log(i, s[i]);
}
/* Prints:
0 H
1 e
...
*/
*/
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