Bug 19967 - Variables named "name" become strings
Summary: Variables named "name" become strings
Status: RESOLVED CONFIGURATION CHANGED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebCore JavaScript (show other bugs)
Version: 528+ (Nightly build)
Hardware: Mac (Intel) OS X 10.5
: P4 Minor
Assignee: Cameron Zwarich (cpst)
URL: http://www.tip.it/runescape/index.php...
Keywords:
Depends on:
Blocks:
 
Reported: 2008-07-09 15:01 PDT by Tamal White
Modified: 2022-06-03 05:46 PDT (History)
7 users (show)

See Also:


Attachments
[TEST]: Test to Compare Browsers (205 bytes, text/html)
2010-07-04 20:42 PDT, Joseph Pecoraro
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Tamal White 2008-07-09 15:01:49 PDT
Run this bit of code in Safari 3.1 or Webkit nightly:

javascript:name=names=new Array("foo","bar","bang");alert(typeof(name)+"/"+typeof(names));

or

javascript:name=names=function() { return "foo" };alert(typeof(name)+"/"+typeof(names));

It appears that if the variable name is "name", it is automatically typed as a string. In the URL provided, this is causing a problem when using name.length with a for loop. The loop is iterating over every character in the string instead of elements in an array.
Comment 1 Cameron Zwarich (cpst) 2008-07-09 16:31:06 PDT
It seems that either the getter or the setter for the window.name property is converting the value to a string. This is an interesting bug, but it shouldn't be too hard to fix.
Comment 2 Joseph Pecoraro 2010-05-07 09:57:21 PDT
I think this is expected behavior. window.name is an actual property to set the (string) name of the browsing context:
http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#apis-for-creating-and-navigating-browsing-contexts-by-name
Comment 3 Alexey Proskuryakov 2010-05-07 22:39:33 PDT
Compare to:

javascript:window.name=new Array("foo","bar","bang");alert(typeof(window.name));

In Firefox, this says "string", but the original test case says "object". So, this is more about what "name" refers to in different contexts, not about window.name behavior.
Comment 4 Joseph Pecoraro 2010-05-07 23:19:37 PDT
(In reply to comment #3)
> So, this is more about what "name" refers to in different contexts,
> not about window.name behavior.

I disagree. The three cases seen here all show window.name is type string, and that the same value in a different variable shows a different type. I believe this was the original way that the author was trying to show that typeof window.name is always string.

> javascript:name=names=new Array("foo","bar","bang");alert(typeof(name)+"/"+typeof(names));

  typeof name => "string"
  typeof names => "object"

> javascript:name=names=function() { return "foo" };alert(typeof(name)+"/"+typeof(names));

  typeof name => "string"
  typeof names => "function"

Your example is just a simplification of the first.


> In Firefox, this says "string", but the original test case says "object".

It was `names`, not `name` that was object =)


I think you are on the right track about contexts, but that just leads me back to the `window.name` special case. Any time you use the variable with name `name` in the global scope it will be `window.name` and have the special properties. However, if you make a new scope (which I believe can only be down with functions in JavaScript) you get expected results:

> javascript:(function() { var name = 1;  alert(typeof name); })()

  typeof name => "number"

The special case of `window.name` can be recreated in JavaScript using a getter on the global variable. Lets do the same thing with a property named `goose`. A much jollier and less confusing variable name ;)

  (function() {
    var private = ""; // Keep the real data private
    window.__defineGetter__('goose', function() {
      return private;
    });
    window.__defineSetter__('goose', function(x) {
      private = String(x);
      return x; // Preserve chain behavior
    });
  })()

Now usage appears the same as `window.name`

  var goose = [1,2,3];
  typeof goose;         // "string"
  goose;                // "1,2,3"
  
  var name = [1,2,3];
  typeof name;          // "string"
  name;                 // "1,2,3"

Its worth noting that using var multiple times is not a syntax error, and does nothing if the variable is already in initialized.

  var x = 10;
  var x = 5; // harmless, but frowned upon
Comment 5 Alexey Proskuryakov 2010-05-07 23:36:54 PDT
>> In Firefox, this says "string", but the original test case says "object".
> It was `names`, not `name` that was object =)

In fact, both are objects. For the first case in bug description, Firefox 3.5 says object/object.

Are you running each test in a new window or tab?
Comment 6 Joseph Pecoraro 2010-05-08 00:30:43 PDT
(In reply to comment #5)
> >> In Firefox, this says "string", but the original test case says "object".
> > It was `names`, not `name` that was object =)
> 
> In fact, both are objects. For the first case in bug description, Firefox 3.5
> says object/object.

This is very fascinating to me. Thanks for pointing it out.

It looks like Firefox special cases a number of the properties on Window. A glance at their IDL files shows a comment that these variables are "replaceable". So you end up with the following behavior:

  window.name;            // ""
  window.name = 1;        // (the result is 1, expected chainable assignment)
  window.name;            // "1"
  window.name = [1,2,3];  // (same thing, chainable)
  window.name;            // "1,2,3"
  
  // First time the user accesses the global "name" things go wild!
  name = 1;
  window.name;            // 1 (what!?!?!)
  window.name = [1,2,3];
  window.name;            // [1,2,3]

My guess is that Firefox was trying to save developers from the weirdness that is window.name. I don't really know which behavior I would recommend. So here is a test case:

  (function() {
    var arr = [];
    arr.push( typeof window.name ); 
    window.name = 1;
    arr.push( typeof window.name );
    name = 1;
    arr.push( typeof window.name );
    alert( arr );
  })();

Produces the following values in the browsers I have on my system:

  Safari 4.0.5 / WebKit Nightly and Chrome 5
  "string,string,string"

  Firefox 3.6.3 and Opera 10.5.3
  "string,string,number"

My interpretation of the HTML5 spec sides with Safari / Chrome. However, that doesn't mean its right. I did a quick search through the WHATWG archives and didn't see any discussion on the lists. There was something interested, and I would say "related" but not the same on public-html:
http://lists.w3.org/Archives/Public/public-html/2009Nov/0302.html
Comment 7 Joseph Pecoraro 2010-05-08 10:26:51 PDT
I dug a bit more. That public-html link pointed to an HTML5 bug:
http://www.w3.org/Bugs/Public/show_bug.cgi?id=8241

It describes new WebIDL properties [ReplaceableNamedProperties] and [Replaceable]. Only the latter seems to be defined in WebIDL, and it matches the weirdness I saw above:
http://dev.w3.org/2006/webapi/WebIDL/#Replaceable

However, the HTML5 spec doesn't make window.name replaceable. Just a bunch of other properties!
http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#the-window-object
Comment 8 Alexey Proskuryakov 2010-05-08 10:36:36 PDT
WebKit also has the notion of replaceable properties, see e.g. DOMWindow.idl.

It would seem that adding [Replaceable] to the name attribute in our IDL could solve this, but I actually suspect that this has been discussed and investigated before, and could have been an intentional choice. Maybe you could try this change, and see which tests break?
Comment 9 Alexey Proskuryakov 2010-06-23 17:49:50 PDT
See also: bug 41003.
Comment 10 Joseph Pecoraro 2010-07-04 20:42:27 PDT
Created attachment 60491 [details]
[TEST]: Test to Compare Browsers
Comment 11 Ahmad Saleem 2022-05-29 08:44:24 PDT
Outputs from all browsers:

Safari 15.5 on macOS 12.4 - string,string,string
Firefox Nightly 102 - string,string,string
Chrome Canary 104 - string,string,string

Since all browsers are consistent and have same output to attached test case. I think this bug should be closed and if there is spec issue then it should be raised separately. Thanks!
Comment 12 Alexey Proskuryakov 2022-05-31 09:51:41 PDT
Thank you for checking! Seems like the spec hasn't changed in this regard, so follow-up may be necessary indeed.
Comment 13 Anne van Kesteren 2022-06-03 05:46:40 PDT
The specification always reflected WebKit here I think. So Firefox must have changed at some point to no longer have this property as `[Replaceable]`. All seems good. \o/