Bug 141184 - REGRESSION: Function declaration inside a function and using the same name as an argument to the containing function no longer takes precedence over the argument
Summary: REGRESSION: Function declaration inside a function and using the same name as...
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified OS X 10.10
: P2 Normal
Assignee: Nobody
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2015-02-02 19:05 PST by Rob Brackett
Modified: 2015-02-09 09:52 PST (History)
3 users (show)

See Also:


Attachments
Simple test case for function declaration names vs. argument names (1.51 KB, text/html)
2015-02-03 01:48 PST, Rob Brackett
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Rob Brackett 2015-02-02 19:05:33 PST
Using the latest WebKit Nightly (r179474), I ran into a problem using code like the following:

```
(function(Thing) {
	Thing.whatever = "This breaks.";
	function Thing() {
		return this;
	}
})()
```

An exception is thrown on line 2 above, when trying to assign to `Thing.whatever`. The exception is “TypeError: undefined is not an object (evaluating 'Thing.whatever = "This breaks."')“ It seems that, on line 2, `Thing` evaluates to the first argument of the containing function (which is undefined) instead of the function defined in line 3. This differs from the currently shipping version of Safari, where `Thing` on line 2 evaluates to the function declaration instead of to `undefined`.

A quick perusal of section “10.5 Declaration Binding Instantiation” in the ECMA-262 spec _seems_ like the new behavior is correct, though I’m honestly not sure I’m reading it right. However, this behavior differs from previous builds of JSC and from many other JS engines (V8, Spidermonkey). It also breaks code existing in the wild — I encountered this while browsing a site built using Instapaper’s web app (http://instapaper.com), which I believe is using Browserify, which creates code like the above example.
Comment 1 Rob Brackett 2015-02-02 19:20:53 PST
Well, in the process of writing a test for this, it seems like this only fails when the inspector is open, so this might not actually be JSC, but instead something about the web inspector.

Still not sure why Instapaper doesn’t work in WebKit Nightly; assuming it’s unrelated to this (and hard to determine since the inspector can’t be open!) :(
Comment 2 Rob Brackett 2015-02-03 01:41:39 PST
OK! This took a fair amount of poking before I finally narrowed it down. The cause of the problem I was seeing on Instapaper was actually code in the form:

```
(function(Thing) {
  Thing.whatever = "This breaks.";
  function Thing() {
    // referencing `Thing` in this inner scope here is what does it
    Thing;
  }
})()
```

It seems like referencing `Thing` inside the `Thing` function inside a function with `Thing` as an argument (wow) causes `Thing` in the outer function to reference the argument instead of the function declaration.

As far as what I was seeing with the inspector open, I have no idea whether it was related or completely different. Whether or not the cause is the same, the symptoms are.
Comment 3 Rob Brackett 2015-02-03 01:48:00 PST
Created attachment 245929 [details]
Simple test case for function declaration names vs. argument names
Comment 4 Radar WebKit Bug Importer 2015-02-03 11:05:37 PST
<rdar://problem/19702564>
Comment 5 Rob Brackett 2015-02-09 09:52:50 PST
FWIW, I have encountered this issue on several more sites in regular browsing. It may be an odd construction, but it’s definitely a real-world problem.