8

是的,是的,我知道,严格模式还没有出现,但实际上,我正在为未来做计划......

那么,为什么会这样:

$('#'+ $(this).attr('id').replace('control-', 'legend-')).fadeIn();

...在 ES5 严格模式下不允许?

还是我误解了?JSLint:

第 516 行字符 18 处的问题:严格违反。

能不能再详细一点,我想知道...?

编辑:

为避免混淆,这里有更多的原始代码:

function displayLegend() {
    $('#'+ $(this).attr('id').replace('control-', 'legend-')).fadeIn();
}
4

2 回答 2

6

JSLint中这段代码的一些试错

"use strict";
var that="dd";
function $(x){return x;}

$('#'+ $(this).attr('id').replace('control-', 'legend-')).fadeIn();
$(this);

告诉我出了什么问题:您正在this用作参数。将两个thises 都更改为thats 不会触发错误。

正如规范所说:

如果this在严格模式代码中进行评估,则this值不会被强制转换为对象。nullundefinedthis值不会转换为全局对象,原始值也不会转换为包装器对象。通过函数调用传递this值(包括使用Function.prototype.applyFunction.prototype.call进行的调用)不会将传递的this值强制传递给对象10.4.311.1.115.3.4.315.3。 4.4 )。[我的重点]

正如约翰雷西格所写

最后,解决了一个长期存在的(并且非常烦人的)错误:null 或 undefined 被强制成为全局对象的情况。严格模式现在可以防止这种情况发生并引发异常。

(function(){ ... }).call( null ); // Exception

正如您所展示的,在函数声明中使用您的代码行会在 JSLint 中引发错误,而在函数表达式中使用它不会。看起来 JSLint 错误地解析了函数声明,看到this在那一刻仍然未定义,并引发异常。

在这一点上,我想我必须引用Juriy Zaytsev ('kangax') 的话

真的有关系吗?

很高兴了解严格模式不是必需的,而只是一种选择。它为那些需要它并愿意应对(并享受)后果的人提供更严格的规则。


更新:最后我找到了解释。如果您阅读此线程,尤其是从消息 #1512 开始,您会阅读到

ES5/strict 的重点是禁止泄漏全局对象,这是 ES3 混杂做的事情。ES5/strict 的一些工作是动态的,而它的一些工作是静态的。JSLint 以静态方式完成所有工作,因此它必须更加严格,才能最好地帮助您正确编写程序。[#1553 中的道格拉斯·克罗克福德]

我不得不承认他有一个正确的观点:如果你的目标是避免全局命名空间污染,那么无论如何你不应该使用函数声明,而应该使用私有命名空间内的函数表达式。但我同意上述线程中的其他人的观点,即错误消息应该更明确(并且可能在遇到函数声明时发出警告)。

于 2010-12-01T11:12:52.437 回答
3

按照 David Dorward 的说法,我找到了通过 JSLint 测试的东西。这对于它为什么这样做是非常奇怪的。

之前:(见问题)

后:

var displayLegend = function () {
    $('#'+ $(this).attr('id').replace('control-', 'legend-')).fadeIn();
};

编辑:

我问道格拉斯·克罗克福德:

JSLint 仅在严格模式下允许在显然打算作为方法调用的函数中执行此操作。所以写

object.property = function () {
    ... this ...
};

这证实了它在规范中所说的内容,但它更清晰!

于 2010-12-01T11:29:30.950 回答