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

发布于 2024-10-05 13:11:38 字数 457 浏览 6 评论 0原文

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

那么,为什么会这样:

$('#'+ $(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();
}

Yeah, yeah, I know, strict mode ain't around yet, but really, I'm planning for the future...

So, why is this:

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

... not allowed in ES5 Strict mode?

Or am I misinterpreting? JSLint:

Problem at line 516 character 18: Strict violation.

Could it be a little more verbose, I wonder...?

EDIT:

To avoid confusion, here's more of the original code:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

魔法唧唧 2024-10-12 13:11:38

JSLint 中这段代码的一些试验和错误

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

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

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

正如规范所述:

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

正如 John Resig 写入

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

(function(){ ... }).call( null ); // 例外

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

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

这真的很重要吗?

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


更新:最后我找到了一个解释。如果您阅读 这个帖子,特别是从消息#1512开始,你会读到

ES5/strict的要点是禁止
全局对象泄漏,
ES3 混杂地做了一些事情。
ES5/strict 完成了一些工作
动态地,以及它的一些工作
静态地。 JSLint 完成了所有的工作
静态工作,所以它必须是均匀的
为了提供最好的帮助而采取更多的限制
你的程序是正确的。 [Douglas Crockford in #1553]

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

Some trial-and-error of this code in JSLint

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

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

shows me what's wrong: you're using this as a parameter. Changing both thises to thats doesn't trigger the error.

As the specification says:

If this is evaluated within strict mode code, then the this value is not coerced to an object. A this value of null or undefined is not converted to the global object and primitive values are not converted to wrapper objects. The this value passed via a function call (including calls made using Function.prototype.apply and Function.prototype.call) do not coerce the passed this value to an object (10.4.3, 11.1.1, 15.3.4.3, 15.3.4.4). [my emphasis]

As John Resig writes,

Finally, a long-standing (and very
annoying) bug has been resolved: Cases
where null or undefined is coerced
into becoming the global object.
Strict mode now prevents this from
happening and throws an exception
instead.

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

As you showed, using your line of code inside a function declaration throws an error in JSLint, whereas using it inside a function expression doesn't. It looks like JSLint erroneously parses the function declaration, sees this, that's still undefined at that moment, and throws an exception.

At this point, I think I have to quote Juriy Zaytsev (‘kangax’):

Does it really matter?

It’s good to understand that strict mode is not a requirement, but is
merely an option. It is there to
provide stricter rules for those who
need it, and are willing to cope with
(and enjoy) consequences.


Update: At last I found an explanation. If you read this thread, especially from message #1512 onwards, you'll read that

The point of ES5/strict is to prohibit
leaking of the global object,
something that ES3 does promiscuously.
ES5/strict does some of its work
dynamically, and some of its work
statically. JSLint does all of its
work statically, so it must be even
more restrictive in order to best help
you get your program right. [Douglas Crockford in #1553]

I have to admit that he has a valid point here: if your goal is to avoid global namespace pollution, you shouldn't use function declarations, but function expressions inside a private namespace, anyway. But I agree with others in the mentioned thread that the error message should be more explicit (and probably throw a warning on encountering a function declaration).

审判长 2024-10-12 13:11:38

按照 David Dorward 的说法,我发现了一些通过 JSLint 测试的东西。至于为什么要这么做,这真是太奇怪了。

之前:(参见问题)

之后:

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

编辑:

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

JSLint 仅在严格模式下允许这样做
在明显的函数中
旨在被称为方法。所以

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

了规范中所说的内容,只是更加清晰!

Following what David Dorward said, I found something that passes JSLint's test. This is downright strange as to why it's doing that.

Before: (see question)

After:

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

EDIT:

I asked Douglas Crockford:

JSLint only allows this in strict mode
in functions that are obviously
intended to be called as methods. So
write

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

This confirms what it says in the spec, except it's much clearer!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文