为什么在严格模式下这是非法的?

时间:2010-12-01 10:48:19

标签: javascript ecmascript-5 strict use-strict

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

那么,为什么会这样:

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

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

还是我误解了? JSLint的:

Problem at line 516 character 18: Strict violation.

我想知道它会更加冗长吗?

编辑:

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

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

2 个答案:

答案 0 :(得分:6)

JSLint

中此代码的一些反复试验
"use strict";
var that="dd";
function $(x){return x;}

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

向我显示错误:您使用this作为参数。将this es更改为that s不会触发错误。

正如the specification所说:

  

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

John Resig writes

  

最后,一个长期存在的(非常   烦人)bug已经解决:案例   其中强制为null或undefined   成为全球对象。   严格模式现在阻止了这种情况   发生并抛出异常   代替。

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

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

此时,我想我必须引用Juriy Zaytsev (‘kangax’)

  

真的重要吗?

     

很高兴理解严格模式不是必需的,但是   只是一个选择。它就在那里   为那些谁提供更严格的规则   需要它,并愿意应付   (并享受)后果。


更新:最后我找到了解释。如果您阅读this thread,特别是从第1512条消息开始,您将阅读

  

ES5 /严格的要点是禁止   泄露全球物体,   ES3做的事情是混杂的。   ES5 / strict做了一些工作   动态的,以及它的一些工作   静态。 JSLint完成了所有工作   静静地工作,所以必须是平等的   限制性更强,以便获得最佳帮助   你的程序正确。 [道格拉斯·克罗克福德在#1553]

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

答案 1 :(得分:3)

按照David Dorward的说法,我发现了一些通过JSLint测试的东西。对于它为什么这样做,这是完全奇怪的。

之前:(见问题)

后:

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

编辑:

我问Douglas Crockford:

  

JSLint仅在严格模式下允许此操作   在显然的功能   意图被称为方法。所以   写

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

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