![]() |
Unexpected scope question
Hello, I would call myself a fairly competent JavaScript programmer,
but I ran into something expected today. Here's a snippet: NS.MyClass = function () { var initialize = function() { /* do something */ NS.Instances[<uniqueId>] = this; } initialize(); } var obj = new NS.MyClass(); The object that ends up in NS.Instances[<uniqueId>] is DOMWindow, not the particular instance of that class. I can obviously fix it with call() but I've found a hole in my knowledge and am trying to understand. Could someone explain what is happening there? Thanks! R |
Re: Unexpected scope question
On Feb 5, 9:39*pm, risingfish <risingf...@gmail.com> wrote:
> Hello, I would call myself a fairly competent JavaScript programmer, > but I ran into something expected today. Here's a snippet: > > NS.MyClass = function () { > > * * var initialize = function() { > * * * * /* do something */ > * * * * NS.Instances[<uniqueId>] = this; > * * } > > * * initialize(); > > } > > var obj = new NS.MyClass(); > > The object that ends up in NS.Instances[<uniqueId>] is DOMWindow, not > the particular instance of that class. I can obviously fix it with > call() but I've found a hole in my knowledge and am trying to > understand. Could someone explain what is happening there? The bigger question is why you've decided to write JavaScript in this manner. Why do you have an inner function in the first place? |
Re: Unexpected scope question
On Feb 5, 10:39*pm, risingfish <risingf...@gmail.com> wrote:
> Hello, I would call myself a fairly competent JavaScript programmer, > but I ran into something expected today. Here's a snippet: > > NS.MyClass = function () { > > * * var initialize = function() { > * * * * /* do something */ > * * * * NS.Instances[<uniqueId>] = this; > * * } > > * * initialize(); > > } > > var obj = new NS.MyClass(); > > The object that ends up in NS.Instances[<uniqueId>] is DOMWindow, not > the particular instance of that class. I can obviously fix it with > call() but I've found a hole in my knowledge and am trying to > understand. From version 5.1 of the ECMA-262 spec (June, 2011) [1]: | 10.4.3 Entering Function Code | The following steps are performed when control enters the execution | context for function code contained in function object F, a caller | provided thisArg, and a caller provided argumentsList: | | 1. If the function code is strict code, set the ThisBinding to thisArg. | 2. Else if thisArg is null or undefined, set the ThisBinding to the | global object. | 3. Else if Type(thisArg) is not Object, set the ThisBinding to | ToObject(thisArg). | 4. Else set the ThisBinding to thisArg. | ... So, when you call `initialize` from within your constructor function without specifically binding `this`, the ThisBinding defaults to the global object. As you say, you can fix this with `call`: | initialize.call(this); You also might want to reconsider having the initialize function redefined for each call to the constructor by storing it in a local closure. Or, if it's as simple as what you've exposed here, remove the inner function altogether, as Michael suggests. -- Scott [1]: http://www.ecma-international.org/pu...T/Ecma-262.pdf |
| All times are GMT. The time now is 06:39 PM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.