From: Alex Shabanov on
Curious javascript sample.

Consider the following code:

var s = "asd"
var f = function() { return typeof(this) }

An expression typeof(s) returns true (as it is expected), but
f.call(s) returns false!

To make matters worse consider the following snippet:

var s = "asd"
var f = function() { return this instanceof String }

An expression f.call(s) returns true, but (s instanceof String)
returns false!


The question is why call transforms this to an object? Is it made for
unification, e.g. to make this iterable using 'for (var i in this)'
loop?

It is also unclear why string literal in fact is not an instance of
String in ("asd" instanceof String) expression but it does a string
in call/apply method invokations.

I see this might be a kind of boxing/unboxing in .NET, but I see no
reason why language designers made such a choice.
From: Thomas 'PointedEars' Lahn on
Alex Shabanov wrote:

> Curious javascript sample.

There is no "javascript": <http://PointedEars.de/es-matrix>

> Consider the following code:
>
> var s = "asd"
> var f = function() { return typeof(this) }
>
> An expression typeof(s) returns true

No, it does not. The expression is supposed to evaluate to and actually
evaluates to "string" in JavaScript 1.8.2, but in this context it evaluates
to "object" in JavaScript 1.8.2. BTW, `typeof' is an operator, so you
should lose the parentheses.

> (as it is expected),

Check your assumptions.

> but f.call(s) returns false!

No, it does not. Because `this' always refers to an object, that call
returns "object".

> To make matters worse consider the following snippet:
>
> var s = "asd"
> var f = function() { return this instanceof String }
>
> An expression f.call(s) returns true,

As expected, see above. The primitive string value that is used as the
thisArg by Function.prototype.call() is converted to an object, a String
instance, when execution enters the function context [ES5, 10.4.3].

> but (s instanceof String) returns false!

Yes, because `s' stores a primitive string value, not a reference to a
String instance.

> The question is why call transforms this to an object?

It does not do that.

> Is it made for unification, e.g. to make this iterable using 'for (var i
> in this)' loop?

You are jumping to conclusions.

> I see this might be a kind of boxing/unboxing in .NET, but I see no
> reason why language designers made such a choice.

While the first result you observed could be a bug in your ECMAScript
implementation, it is more likely that you don't know what you are doing.


PointedEars
--
realism: HTML 4.01 Strict
evangelism: XHTML 1.0 Strict
madness: XHTML 1.1 as application/xhtml+xml
-- Bjoern Hoehrmann
From: Stefan Weiss on
On 13/05/10 00:18, Alex Shabanov wrote:
> Curious javascript sample.
>
> Consider the following code:
>
> var s = "asd"
> var f = function() { return typeof(this) }
>
> An expression typeof(s) returns true (as it is expected), but
> f.call(s) returns false!

In ECMAScript 3, |this| is always an object. call() and apply() will
convert anything passed as the first argument (the "thisArg") to its
object form, except null and undefined:

| If thisArg is null or undefined, the called function is passed the
| global object as the this value. Otherwise, the called function is
| passed ToObject(thisArg) as the this value.
(ECMA-262, 3rd edition, 15.3.4.4)

The ToObject operation is defined in section 9.9.

> To make matters worse consider the following snippet:
>
> var s = "asd"
> var f = function() { return this instanceof String }
>
> An expression f.call(s) returns true, but (s instanceof String)
> returns false!

s is a string primitive (typof s == "string"), and |this| is a String
object (typeof this == "object"). The conversion happened in call().

> It is also unclear why string literal in fact is not an instance of
> String in ("asd" instanceof String) expression but it does a string
> in call/apply method invokations.

The "asd" literal is not an object, so it can't be an instance of
anything at all. There are cases where intermediary objects are
automatically created for primitive types (for example when you read
"asd".length), but instanceof is not one of these cases.

> I see this might be a kind of boxing/unboxing in .NET, but I see no
> reason why language designers made such a choice.

For the lulz? No, sorry, I don't know; you'd have to ask them.
Performance or memory considerations could have played a role (like they
did in Java). Come to think of it, maybe the similarity to Java's
strings and Strings was intended, but I'm only guessing here.


--
stefan
From: VK on
On May 13, 2:18 am, Alex Shabanov <avshaba...(a)gmail.com> wrote:
> The question is why call transforms this to an object?

Because you wanted it. call() sets the context of its first argument,
and it cannot be primitive value (string primitive in your case).
Javascript was originally made in the way to understand bad coding as
long as it's possible, with an armee of non-professional programmers
in mind. So instead of throwing illegal argument error, it wraps
string primitive into String object and works with it. Obviously it
doesn't affect the s string itself, it remains string primitive.
Same Javascript will do with other primitive, i.e.:

var n = 2;

function f() {
window.alert(this instanceof Number);
}


f.call(n); // alerts true

window.alert(typeof n); // number


> It is also unclear why string literal in fact is not an instance of
> String in ("asd" instanceof String) expression but it does a string
> in  call/apply method invocations.

Again, in Javascript there are string primitives and string objects.
By default string literals create string primitives:
var s = "abc";
To make a string object one needs to use constructor:
var s = new String("abc");
but it has little practical sense: Javascript will "upcast" primitives
if needed and downcast when not needed anymore. Say
var len = s.length
it upcast and downcast s to get the length value - because string
primitive has no properties or methods, only String object does.




From: Thomas 'PointedEars' Lahn on
Stefan Weiss wrote:

> Alex Shabanov wrote:
>> var s = "asd"
>> var f = function() { return typeof(this) }
>>
>> An expression typeof(s) returns true (as it is expected), but
>> f.call(s) returns false!
>
> In ECMAScript 3, |this| is always an object. call() and apply() will
> convert anything passed as the first argument (the "thisArg") to its
> object form, except null and undefined:
>
> | If thisArg is null or undefined, the called function is passed the
> | global object as the this value. Otherwise, the called function is
> | passed ToObject(thisArg) as the this value.
> (ECMA-262, 3rd edition, 15.3.4.4)

ES5 specifies it differently, but to the same effect.

>> To make matters worse consider the following snippet:
>>
>> var s = "asd"
>> var f = function() { return this instanceof String }
>>
>> An expression f.call(s) returns true, but (s instanceof String)
>> returns false!
>
> s is a string primitive (typof s == "string"), and |this| is a String
> object (typeof this == "object").

Yes.

> The conversion happened in call().

Depends.


PointedEars
--
Use any version of Microsoft Frontpage to create your site.
(This won't prevent people from viewing your source, but no one
will want to steal it.)
-- from <http://www.vortex-webdesign.com/help/hidesource.htm> (404-comp.)