严格违反使用此关键字和揭示模块模式
遇到麻烦得到以下通过jslint / jshint
/*jshint strict: true */ var myModule = (function() { "use strict"; var privVar = true, pubVar = false; function privFn() { return this.test; // -> Strict violation. } function pubFn() { this.test = 'public'; // -> Strict violation. privFn.call(this); // -> Strict violation. } return { pubVar: pubVar, pubFn: pubFn }; }()); myModule.pubFn();
我知道这是由于在函数声明中使用this
引起的,但是我读了Crockford写的东西,他说违规是为了防止全局variables污染 – 但是这里唯一的全局variables就是我明确定义的variables。 myModule
。 其他的一切都在直接的function范围内,我应该可以用this
来指代这个模块。
任何想法如何我可以通过这种模式?
更新:如果我使用函数expression式而不是声明,这似乎工作,即
var pubFn = function () { ...
我不是这种格式的粉丝,更喜欢让函数名和命名参数更接近,声明看起来更清晰。 我真的不明白为什么这是抛出违规 – 这种模式没有理由。
validthis
有一个叫validthis
的选项 ,它:
当代码以严格模式运行时,可以禁止警告严重的违规行为,并且在非构造函数中使用
this
警告,当你肯定你在严格模式下使用this
函数。
在JSHint所抱怨的function中使用它,在你的情况下,看起来像这样:
function privFn() { /*jshint validthis: true */ return this.test; // -> No Strict violation! } function pubFn() { /*jshint validthis: true */ this.test = 'public'; // -> No Strict violation! privFn.call(this); // -> No Strict violation! }
看起来很痛苦,不得不在每个函数中指定它,但是如果你在模块函数的顶部设置了这个选项,你可能会隐藏真正严格的模式违规。
这里真正的问题是,如果从模块上下文 (从IIFE内 )调用privFn
,在严格模式下this
将是undefined
; window
如果不是在严格的模式。 唉,如果从IIFE内部调用函数将失败。
这是因为函数在从IIFE内部调用时没有所有者 (对象),而返回的模块对象是从IIFE上下文外部调用的函数的所有者,例如调用myModule.pubFn()
时的this === myModule
myModule.pubFn()
。
严格模式和JSHint / JSLint都试图帮助你,你永远不应该忽略他们产生的错误/警告,而是找出他们为什么警告你。
如果您100%确定privFn
, pubFn
等将不会在您的模块之外的任何地方被调用,只需在任何生成警告的函数中添加comment /*jshint validthis: true */
。 或者,在IIFE中的一个注释将阻止JSHint在模块内部的任何函数上产生这个错误。
许多可能的解决scheme之一
存储这个范围(在这个例子中是self
)来明确地指向模块。 这将显示并确保您的意图。
/*jshint strict: true */ var myModule = (function() { "use strict"; var privVar = true, pubVar = false, self = this; function privFn() { return self.test; } function pubFn() { self.test = 'public'; //privFn.call(this); // Will have no effect, as `privFn` does not reference `this` privFn(); } return { pubVar: pubVar, pubFn: pubFn }; }()); myModule.pubFn();
不幸的是,这是这个设置的预期错误,因为jslint / jshint不知道在全局上下文中声明的函数将被用作对象方法。
- SQL Server中的唯一键冲突 – 是否可以安全地使用Error 2627?
- 在FormsAuthentication.SignOut()之后,Page.User.Identity.IsAuthenticated仍然为true。