Prev: Value from select into href's url ?
Next: FAQ Topic - Why do some posts have <FAQENTRY> in them? (2010-05-13)
From: Alex Shabanov on 12 May 2010 18:18 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 12 May 2010 18:37 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 12 May 2010 18:43 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 12 May 2010 18:51 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 12 May 2010 18:54 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.)
|
Next
|
Last
Pages: 1 2 Prev: Value from select into href's url ? Next: FAQ Topic - Why do some posts have <FAQENTRY> in them? (2010-05-13) |