> Why not use "this" instead of "exports"? for example:
I like how "exports" is very explicit. If you read "exports.add = function () ...", then you immediately know that it is an export. To understand "this.add = ..." you need to read more context.
> I like how "exports" is very explicit. If you read "exports.add = > function () ...", then you immediately know that it is an export. To > understand "this.add = ..." you need to read more context.
All context layers in javascript use this; why should the top level context be different? Why introduce a new keyword. I'd rather view module files as constructor functions for objects.
"exports" is *not* a keyword. Because of the bizarre behavior
associated with "this" in JS, several secure JS subsets (ADsafe,
Cajita, perhaps dojox secure?) ban it. Others (Jacaranda) severely
restrict its use.
On Fri, Apr 10, 2009 at 6:58 AM, Ryan Dahl <coldredle...@gmail.com> wrote:
>> I like how "exports" is very explicit. If you read "exports.add =
>> function () ...", then you immediately know that it is an export. To
>> understand "this.add = ..." you need to read more context.
> All context layers in javascript use this; why should the top level
> context be different? Why introduce a new keyword. I'd rather view
> module files as constructor functions for objects.
> Because of the bizarre behavior
> associated with "this" in JS, several secure JS subsets (ADsafe,
> Cajita, perhaps dojox secure?) ban it. Others (Jacaranda) severely
> restrict its use.
Observation: a large portion of "this" abuses and misuses is just simply a
result of poor knowledge of how "this" works in {java,ecma}script. Clearly,
I am not stating that all people mentioned in the post above have low JS
skills, but I have personally met a _huge_ amount of people confused with
"this" just because they were not sufficiently familiarized with how it
works.
In fact, I tend to agree with author of this thread. Having "exports" gives
us sufficient "explicitness", but in fact introduces a new "reserved" word -
and there are _plenty_ of problematic words ("super", "class", "char" and
many more - see
https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Reserv...)
in JS that cannot be used just because they are reserved.
> On Fri, Apr 10, 2009 at 6:58 AM, Ryan Dahl <coldredle...@gmail.com> wrote:
> >> I like how "exports" is very explicit. If you read "exports.add =
> >> function () ...", then you immediately know that it is an export. To
> >> understand "this.add = ..." you need to read more context.
> > All context layers in javascript use this; why should the top level
> > context be different? Why introduce a new keyword. I'd rather view
> > module files as constructor functions for objects.
> In fact, I tend to agree with author of this thread. Having "exports" > gives us sufficient "explicitness", but in fact introduces a new > "reserved" word - and there are _plenty_ of problematic words > ("super", "class", "char" and many more - see > https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Reserv...) > in JS that cannot be used just because they are reserved.
exports will neither become reserved in any way, nor is it. It's just a variable that is part of the securable modules API. (However, export without s is a reserved word.)
On Fri, Apr 10, 2009 at 3:58 AM, Ryan Dahl <coldredle...@gmail.com> wrote: > All context layers in javascript use this; why should the top level > context be different? Why introduce a new keyword. I'd rather view > module files as constructor functions for objects.
It's funny that you should mention jQuery. I wasn't aware that they had finally shifted from using "window" directly to using "this". I made this recommendation two years ago so that you could make this argument today ;-) http://dev.jquery.com/ticket/1794.
Ihab and I also recommended that "this" be a synonym for "exports" to support a migration phase where modern day scripts could also be used as modules. The rationale is described in the section "Global/Salty Script/Module" in "Importing Capabilities and Exporting a Module" in our proposal to ECMA http://docs.google.com/Doc?id=dfgxb7gk_34gpk37z9v&hl=en
However, "exports" is a better way to refer to explicitly denote exported stuff for a couple reasons. For one, it would resemble our intended syntax in a future ECMAScript standard, "export foo" being sugar for "exports.foo". It also provides a name by which exports can be referenced in /any/ nested scope; using "this" is a hazard in those scope because it can be subverted by a third-party function caller. Also, for the reasons Mark outlines, "this" is banned in most security contexts, so to be interoperable, a module must not use "this" and therefore must use the term "exports".
Also, the use of "exports" is not going to cause the same difficulties as reserved keywords in the language. It is not a keyword, so you can reassign it, declare variables by the same in inner scope, and any of the other freedoms we as JavaScripters enjoy. A script may blissfully use the term without knowledge that it's already in scope. Thankfully "export" and "import" are reserved keywords, since we would like to repurpose them in the future for "exports" and "require" sugar and would not have such an opportunity otherwise.
While I am strongly in favor of providing a migration phase for modern scripts, we as application programmers tend to do anything that works and suits our fancy without regard or awareness of the tradeoffs, such that if "this" is permitted to be used to refer to exports, it certainly will be abused. For those that care, Chiron still permits the use of "this" as a synonym for "exports" so that global scripts can migrate for the time being, and I feel that addressing this issue only in a client-side loader is sufficient and there need not be a resolution by this group either requiring or disallowing the use of "this" as a synonym of "exports".
Ihab and I also recommended that "this" be a synonym for "exports" to
> support a migration phase where modern day scripts could also be used > as modules.
This, however, precludes having modules with private functions and variables, AFAICS.
Consider the case of modules that look like this; if the outermost "this" is the module's scope, "myPrivateState" and "secretStuff" suddenly become module exports:
var myPrivateState = 3; function secretStuff() { ;
Later the programmer decides that submodule should be in its own file. The programmer creates a directory module/ and a file module/submodule.js. Now he is faced with the task of renaming "this.hello" to "exports.hello". Obviously this is not a huge problem but it demonstrates that "this" is natural to export objects out of the scope.
On Sun, Apr 12, 2009 at 4:14 AM, Ryan Dahl <coldredle...@gmail.com> wrote:
> > This, however, precludes having modules with private functions and > > variables, AFAICS.
> If you just take the module file and wrap it in a constructor then it would
> function require () { > return new function () { (module code) } > }
1. Modules can't rewrite the require function; that breaks basic security. 2. Without rewriting require, sharing private variables among exported functions starts to get a little ridiculous IMHO 3. "this" is certainly not the most natural way to export things, except when there is no other choice. (Using a screwdriver to bang nails works; doesn't mean you shouldn't use a hammer when one is available) 4. You seem to be making the assumption that modules usually supply a single class, rather than a group of related things. I don't believe that is a reasonable assumption. 5. Have you taken a look at the discussions last month w.r.t. mutually-dependent module loading? 6. "Ease of porting" is a complete red herring. "for (el in this) exports[el] = this[el];" 7. I am really getting sick and tired of talking about modules. They were beaten to death in Jan, Feb and March. If we keep bike shedding like this, we're going to be sitting here next year doing the same damned thing. Once again I am forced to wonder if people on this list are actually interested in CREATING a viable ssjs ecosystem, or opining about the prettiest one. I would argue that having a working environment to try things in is way more important than talking about what might be, and changing hats every other week.
Wes
-- Wesley W. Garland Director, Product Development PageMail, Inc. +1 613 542 2787 x 102
> 1. Modules can't rewrite the require function; that breaks basic security.
I didn't explain myself well. I wasn't suggesting modules rewrite the require function, rather I was suggesting that the data in a module file be thought of the body of a constructor function. When viewed this way, "this" is the natural a scope exporter.
> 4. You seem to be making the assumption that modules usually supply a single > class, rather than a group of related things. I don't believe that is a > reasonable assumption.
No..? Or maybe I miss understand you. For example:
var module = new function () { function PrivateClass () { /* ... */ } this.PublicClass1 = function () { /* ... */ }; this.PublicClass2 = function () { /* ... */ }; };