【问题标题】:Does javascript use some sort of implicit "noop" call?javascript 是否使用某种隐式的“noop”调用?
【发布时间】:2014-09-29 13:34:01
【问题描述】:

这可能是 JS 101 但是...

对 JS 引擎有更好理解的人能否向我解释一下为什么字符串文字、整数等会被 JS “忽略”或视为有效代码?

JS Hint 确实给出了“意外表达式”报告,但代码仍然有效并运行。

我创建了以下笔,希望能解释我在这里的意思。

http://codepen.io/billythekid/pen/zyGbi/

var span = document.getElementsByTagName('SPAN')[0];

// let's show what I'm trying to say here by way of an expanded example.
function foo()
{
  var bar = "something";
}
foo(); // does nothing useful, but returns nothing either - valid and understandable;

function baz()
{
  return "nothing"; // a string
}

function zoo()
{
  return 250; // an integer
}

var a = baz(); // the variable holds the return value. The function is evaluated and the return value is assigned to the variable.
span.innerHTML += a+"<br>";

baz(); // produces no error despite the function returning a value. Why doesn't the JS engine see this as the evaluated string "something" and try to run the string as a JS command?
span.innerHTML += "this code has run, so the JS didn't break above. Why wasn't the returned string parsed and invalid?<br>";

"something"; // the string literal
span.innerHTML += "this code has run, so the JS didn't break above. So why not? How is a string literal valid JS? Why no errors?<br>";

var b = zoo();
span.innerHTML += b+"<br>";

zoo();// produces no error despite the function returning a value. Why doesn't the JS engine see this as the evaluated integer 250 and try to run the string as a JS command?
span.innerHTML += "this code has run, so the JS didn't break above. So why not? How is an evaluated integer valid JS? Why no errors?<br>";

250; // the integer literal
span.innerHTML += "this code has run, so the JS didn't break above. So why not? How is an integer literal valid JS? Why no errors?<br>";

eval(250); // the integer literal
span.innerHTML += "this code has run, so the JS didn't break above. So why not? How is an evaluated integer literal valid JS? Why no errors?<br>";

eval("something"); // the string literal
span.innerHTML += "this code broke, it can't run a string that's not been defined as a function or whatever.<br>";

// and, had the previous code not broken...
non_func(); // doesn't exist!
span.innerHTML += "this code doesn't run! So it'll error out with a call to a function/variable that doesn't exist but not eval'd code that isn't JS, such as a string, or even the literals of these objects!<br>";

// It appears that anythign not explicitly wrapped in an eval function is ignored by JS rather than throwing any errors. Why is this?

只需运行一个字符串文字,例如“foo”;作为控制台中的一行似乎返回自身。

JS 是在内部以某种“noop”方法或内部垃圾收集此类事情的方式将这些简单的情况包装起来,还是只是在代码通过它之后将代码视为“运行”并且无事可做(比如给变量赋值,还是别的什么?

我在使用 setInterval() 调用时考虑到这一点,如果我将它的返回值(嗯,它是 ID 标识符)分配给一个 var 以便稍后在 clearInterval 中使用它是有效的,但当我们忽略返回时它也是有效的ID。 ID 没有被“解析”为 JS。

使用严格模式似乎也对这种行为没有影响。

希望我没有让这变得比需要的更混乱。 :oD

【问题讨论】:

  • 该语言的语法表明任何表达式都可以用作语句,就是这样。 (是的,你让这变得比它需要的更混乱。)
  • “希望我没有让这件事变得比它需要的更混乱” 我认为你是 waaaay 想太多了。
  • 这与松散的打字无关。许多像 C 和 Java 这样的语言让你忽略子程序的返回值
  • 我想这是一个很好的术语。关键是,JS 应该易于使用且易于学习。因此,有很多内置的快捷方式可以实现这种效果。确定它是如何工作的确实没有意义。放心吧。
  • 这可能并不完全是一个 noop,因为如您所知,use strict 是以相同的方式完成的,因此它可能至少必须检查它是否是一个 use strict 语句。我想在那之后可以忽略它。

标签: javascript computer-science


【解决方案1】:

您的困惑背后的一大罪魁祸首是 C 编程语言。其中,很多你认为是语句的东西,比如赋值,其实都是表达式。

//This is valid C and Javascript code
x = (y += 1);

//We all have been bitten by this one once haven't we?
while(x = y){
}

为了让这些语句在它们自己的行中使用,在语言语法中有一条规则,让一个后跟分号的表达式算作一个语句

stmt :=
   <if_then_else> |
   <while loop> |
   ... |
   <expression> ';'

评估这些单表达式语句的规则是评估表达式的副作用并且忽略它的值。

Javascript(和许多其他语言)从 C 语法中借鉴了很多东西,包括对表达式的这种特殊处理。使用字符串作为语句对其值没有任何作用(除非字符串是“use strict” - 那么它是一个有用的hack,它在新浏览器中执行某些操作但在旧浏览器中没有任何作用)。使用函数调用作为语句运行它会产生副作用并忽略它的返回值。如果你忽略返回值,一些更吝啬的语言,比如 Haskell 或 Go 会抱怨,但 C 和 Javascript 只会把它们扔掉。

-- In Haskell you get a compiler warning for ignoring return values
do
   functionThatReturnsNothing()
   a <- functionThatReturnsAValue()
   _ <- functionThatReturnsAValue() -- unless you ignore it explicitly

似乎任何没有明确包装在 eval 函数中的东西都会被 JS 忽略,而不是抛出任何错误。

感谢上帝就是这样!如果事情像这样被隐式评估并且字符串不应该作为代码运行,除非你明确说明它,否则很容易出错!

【讨论】:

  • 这是一个很好的解释。我已经接受它“只是”这么久了,我不再注意到“noop”正在发生。我之前正在查看一些旧的 mIRC 脚本代码,并记得如何明确需要告知 noop 返回值,否则会出错。因此我的思路就在这里。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-20
  • 2013-03-21
  • 1970-01-01
  • 2021-09-13
相关资源
最近更新 更多