Javascript 对象。原型方法和';使用严格的';在IIFE中(立即调用的函数表达式)
原代码:Javascript 对象。原型方法和';使用严格的';在IIFE中(立即调用的函数表达式),javascript,inheritance,anonymous-function,iife,Javascript,Inheritance,Anonymous Function,Iife,原代码: 'use strict'; function GitJs(config) { var defaults = { inheriting: false, clientId: undefined, accessToken: undefined, baseUrl: 'https://api.github.com', mode: 'read' }; this.config = $.exten
'use strict';
function GitJs(config) {
var defaults = {
inheriting: false,
clientId: undefined,
accessToken: undefined,
baseUrl: 'https://api.github.com',
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;
};
...
新守则:
(function() {
'use strict';
'use strict';
function GitJs(config) {
var defaults = {
inheriting: false,
clientId: undefined,
accessToken: undefined,
baseUrl: 'https://api.github.com',
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;
};
...
}());
按照此代码,当我尝试:
var gitjs=new gitjs()代码>
我听说GitJs是未定义的
我到底在想什么:
- 我不想在每个方法中都使用严格的
- 如果代码被缩小并连接到另一个文件,我希望代码能够很好地发挥作用
- 我想使用
.prototype
语法,以便于以后继承(和代码清晰)
- 我不想创建一个全局
var gitJs
变量,因为它可以被其他人的脚本覆盖
- 我假设用户总是通过
new
关键字调用对象构造函数
说实话,我知道我错了。大错特错。我似乎无法找出我思维中的缺陷所在,我希望得到一些指导。你的问题是GitJS现在是立即调用函数的私有变量。您不能将函数隐藏在私有作用域中,同时使其公开可用。它们是相互排斥的目标
因此,您需要通过窗口显式地设置全局变量
var GitJS;
(function() {
'use strict';
GitJS = function(){ ... }
...
}());
或者从IIFE内部返回导出的函数
var ExportedGitJS = (function(){ //using a different name just to be clear...
'use strict';
var GitJS = function(){ ... }
...
return GitJS;
}());
好吧,我撒谎了。您可以在不依赖全局变量的情况下创建Javascript模块,但这通常意味着还需要使用不同的模块创建约定和/或模块库。如果您对此感兴趣,我强烈建议您进行查看。@missingno是正确的,但我必须补充一点,您离使用或删除该文件只有一步之遥。你对全局变量保持警惕是对的;如果您承诺在具有定义的依赖项的异步模块内运行所有JavaScript,那么您只需将GitJs构造函数返回到全局定义函数,然后在任何需要它的地方都需要GitJs模块
// 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
});
关于提供一些指导,我不确定这听起来是否完全显而易见,但有一种方法可以:
- 不要在每个方法中插入
使用strict
pragma
- 连接时不对其他源施加严格模式
- 使用
.prototype
语法
- 不需要全局
var gitJs
变量
- 让用户通过
new
关键字调用对象构造函数
这是:
/* 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.com',
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();
};
这部分回答了这个问题吗?我开始明白我做错了什么。至于全局var GitJs,我的new
操作员关注点是什么?或者这是没有意义的,因为构造函数无论如何都应该被IIFE调用?IIFE不会调用构造函数;IIFE实际上只是程序(即立即)执行的代码的范围包装器。一旦您的本地范围内有了GitJS,您的新操作员就应该可以工作了,您可以通过设置全局或使用模块加载器来完成。这个答案还没有投票,这显然是实现目标的一种方式,但这真的是我们的最佳实践吗?选民投票?一年后,我肯定会依靠一些全球可用的名称空间来存储GitJs
“类”,而不是把它塞进窗口。然后可以在同一IIFE中定义构造函数和原型,由一个strict
pragma保护,并在函数末尾将类添加到名称空间。