【问题标题】:Using a function in another function before that first function is defined在定义第一个函数之前在另一个函数中使用一个函数
【发布时间】:2014-09-18 15:51:41
【问题描述】:

在编写 API 时,我倾向于将函数按自上而下的顺序排列,最暴露的函数在顶部,辅助函数在底部。但是,当使用var 而不是神奇的function 声明定义函数时,函数在定义之前不能使用。那么如果我们有一个名为$company 的对象并且我们正在定义它的方法呢?我可以以这种方式安全地订购我的 JS 吗?

var $company = {};

$company.foo = function(x) {
    $company.bar(x*x); // used in definition, but not called directly - ok?
};

// $company.bar(6) // this would produce an error

$company.bar = function(x) {
    alert(x);
};

它似乎适用于我当前版本的 Firefox,但我想知道它是否是已定义的行为。是否有任何版本的 IE 会出现这种情况?

【问题讨论】:

  • JS 在你调用它的时候会用到你的函数,所以当你声明 foo 时,bar 可能不存在,但调用 foo 时它应该存在。

标签: javascript function hoisting


【解决方案1】:

是的,你可以。

函数只定义,不执行。

JS 引擎执行文件的每一行:

var $company = {};
$company.foo = ...;
$company.bar = ...;

然后,在$company.foo 执行时,$company.bar 被定义!

【讨论】:

  • 这是有道理的。我在任何地方都找不到明确写的。我确实找到了this other SO answer,它在谈论它。
  • 作为参考答案的作者和长期的 javascript 黑客,我可以告诉你一些关于 javascript/ECMAscript 规范是如何编写的。首先是 Netscape 的实现(只有代码,没有规范)然后微软尽可能地复制它(包括错误)然后人们决定应该有一个标准(主要是因为担心微软会将他们的 js 引擎发展到 100%与其他人不兼容)。这个过程一直持续到今天,Apple 发明的功能成为称为 HTML5 的“标准”,Microsoft 发明的语法成为 SVG 的一部分等。
  • 也许正因为如此,javascript 规范实际上是在尝试尽可能详细地记录当前的 javascript 实现(除了标准委员会无法达成一致的部分)。因此,浏览器恰好具有完全兼容的行为的许多部分被忽略为显而易见的并且仍然没有记录。在过去,我们必须编写测试脚本来弄清楚 js 是如何工作的(尤其是使用 IE,因为我们无法访问源代码)
  • 如果以上所有内容听起来有点吓人(用一种您无法真正完全了解的语言编写代码),那就是。非常非常可怕。
  • 哈,我只是在阅读您的其他一些答案。 :P 我链接的你的答案写得很好,我想我现在明白了。感谢 cmets!
【解决方案2】:

是的,这是可行的,因为没有浏览器(或没有 JavaScript 引擎)会假设 . 的右侧是什么,直到它必须计算左侧的表达式。

但很多人不喜欢这种“向前看”,而是使用回调函数:

 $company.foo = function(x, callback) {
      callback(x*x);
 }

这段代码更明显,更灵活,因为它几乎可以调用任何东西,你可以curry它等等。

【讨论】:

  • 谢谢。我不确定它是否明确地取决于.,因为以下也不会产生错误:var a = function() { b(); }; var b = function() { alert(1); };
  • 嗯,这里有两个效果:JavaScript 将解析函数体(以检查语法错误),但它不会对各个位的含义做出很多假设。所以从某种意义上说,函数体和. 的情况是一样的:只要语法没问题,JavaScript 并不关心(还)主体/右侧是否有意义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-04
  • 1970-01-01
  • 2012-01-15
  • 2012-03-18
相关资源
最近更新 更多