The original Code:
'use strict';
function GitJs(config) {
var defaults = {
inheriting: false,
clientId: undefined,
accessToken: undefined,
baseUrl: '',
mode: 'read'
};
this.config = $.extend(defaults, config);
}
/**
* Gets the jQuery method that GitJs#generateApiRequest is going to use to send the ajax request.
*
* @param {string} httpVerb The HTTP verb that the request will use,
* @return string
*/
GitJs.prototype.getCommandMethod = function (httpVerb) {
var method = $.get;
switch (httpVerb) {
case 'GET':
method = $.get;
break;
case 'POST':
method = $.post;
break;
}
return method;
};
...
The new code:
(function() {
'use strict';
'use strict';
function GitJs(config) {
var defaults = {
inheriting: false,
clientId: undefined,
accessToken: undefined,
baseUrl: '',
mode: 'read'
};
this.config = $.extend(defaults, config);
}
/**
* Gets the jQuery method that GitJs#generateApiRequest is going to use to send the ajax request.
*
* @param {string} httpVerb The HTTP verb that the request will use,
* @return string
*/
GitJs.prototype.getCommandMethod = function (httpVerb) {
var method = $.get;
switch (httpVerb) {
case 'GET':
method = $.get;
break;
case 'POST':
method = $.post;
break;
}
return method;
};
...
}());
As this code stands, when I attempt:
var gitjs = new GitJs();
I am told that GitJs is undefined
What the hell I was thinking:
- I don't want to put
use strict
inside of every method. - I want my code to play nice if it gets minified and concatenated to another file.
- I want to use the
.prototype
syntax for ease of inheritance later on (and code clarity) - I don't want to make a global
var gitJs
variable because it could be overridden by someone else's script. - I assume that the user will always invoke the object constructor via the
new
keyword
For the record, I know I'm wrong. Way wrong. I just can't seem to figure out where the flaw in my thinking lies and I'd love some guidance.
The original Code:
'use strict';
function GitJs(config) {
var defaults = {
inheriting: false,
clientId: undefined,
accessToken: undefined,
baseUrl: 'https://api.github.',
mode: 'read'
};
this.config = $.extend(defaults, config);
}
/**
* Gets the jQuery method that GitJs#generateApiRequest is going to use to send the ajax request.
*
* @param {string} httpVerb The HTTP verb that the request will use,
* @return string
*/
GitJs.prototype.getCommandMethod = function (httpVerb) {
var method = $.get;
switch (httpVerb) {
case 'GET':
method = $.get;
break;
case 'POST':
method = $.post;
break;
}
return method;
};
...
The new code:
(function() {
'use strict';
'use strict';
function GitJs(config) {
var defaults = {
inheriting: false,
clientId: undefined,
accessToken: undefined,
baseUrl: 'https://api.github.',
mode: 'read'
};
this.config = $.extend(defaults, config);
}
/**
* Gets the jQuery method that GitJs#generateApiRequest is going to use to send the ajax request.
*
* @param {string} httpVerb The HTTP verb that the request will use,
* @return string
*/
GitJs.prototype.getCommandMethod = function (httpVerb) {
var method = $.get;
switch (httpVerb) {
case 'GET':
method = $.get;
break;
case 'POST':
method = $.post;
break;
}
return method;
};
...
}());
As this code stands, when I attempt:
var gitjs = new GitJs();
I am told that GitJs is undefined
What the hell I was thinking:
- I don't want to put
use strict
inside of every method. - I want my code to play nice if it gets minified and concatenated to another file.
- I want to use the
.prototype
syntax for ease of inheritance later on (and code clarity) - I don't want to make a global
var gitJs
variable because it could be overridden by someone else's script. - I assume that the user will always invoke the object constructor via the
new
keyword
For the record, I know I'm wrong. Way wrong. I just can't seem to figure out where the flaw in my thinking lies and I'd love some guidance.
Share Improve this question asked Jun 29, 2012 at 2:50 Levi HackwithLevi Hackwith 9,30218 gold badges67 silver badges115 bronze badges3 Answers
Reset to default 4Your problem is that GitJS is now a private variable of the immediately invoked function. You can't hide your function in a private scope and make it publicly available at the same time. They are mutually exclusive goals.
Therefore, you will want to either explicitely set the global variable, via the window
var GitJS;
(function() {
'use strict';
GitJS = function(){ ... }
...
}());
or return the exported function from inside the IIFE.
var ExportedGitJS = (function(){ //using a different name just to be clear...
'use strict';
var GitJS = function(){ ... }
...
return GitJS;
}());
OK, I lied. You can make Javascript modules without having to rely on global variables but that usualy means also using a different module-creation convention and/or using a module library. I would highly remend that you check out http://requirejs/ if you are interested in this.
@missingno is correct, but I have to add that you're just one step from using RequireJS or an equivalent loader. You're right to be leery of global variables; if you mit to running all of your JavaScript inside asynchronous modules with defined dependencies, then you can simply return your GitJs constructor to the global define function, and then require your GitJS module in anything that needs it.
// using the global define function provided by an AMD loader
// assuming that jQuery has already been provided by the paths config
define(['jquery'],function($) {
'use strict';
var GitJS = function() { ... }
return GitJS
});
Regarding giving some guidance, I'm not sure if this sounds pletely obvious, but there is a way to:
- not insert the
use strict
pragma in every method - not impose strict mode on other sources when concatenated
- use the
.prototype
syntax - not require a global
var gitJs
variable - let the user invoke the object constructor via the
new
keyword
There it is:
/* Class constructor, public, globally available */
function GitJs(config) {
'use strict'; /* You may want to drop this one */
var defaults = {
inheriting: false,
clientId: undefined,
accessToken: undefined,
baseUrl: 'https://api.github.',
mode: 'read'
};
this.config = $.extend(defaults, config);
}
/* IIFE to wrap the *main* strict pragma */
(function () {
'use strict';
GitJs.prototype.getCommandMethod = function (httpVerb) {
/* ... */
};
GitJs.prototype.someOtherMethod = function (someParam) {
/* ... */
};
})();
...
/* some other block */
... {
var gitjs = new GitJs();
};
Does this partially respond to the question?
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744395340a4572113.html
评论列表(0条)