为什么总是在JavaScript中声明函数?

Dev*_*oob 5 javascript function

我被告知你必须始终在JavaScript中声明函数.真的吗?它的优点是什么?

我通常将函数分配给变量:

var foo = function() {};
Run Code Online (Sandbox Code Playgroud)

但据说这是错误的,需要做一些堆栈跟踪.有人可以解释一下吗?有人告诉我这样做:

var foo = function fooBar() {};
Run Code Online (Sandbox Code Playgroud)

如果它被分配给一个对象会有意义吗?

var Foo = {};
Foo.Bar = function Bar() {};
Run Code Online (Sandbox Code Playgroud)

请注意,这些功能不在全局范围内,也不是自行执行,也不是多次使用.

Ry-*_*Ry- 3

首先,关于术语的一个小注释:您所拥有的不是\xe2\x80\x99t 函数声明。这是一个函数声明:

\n\n
function fooBar() {\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

它创建一个名为fooBar可通过变量访问的函数fooBar函数。这是涉及命名函数表达式的赋值:

\n\n
var foo = function fooBar() {\n};\n
Run Code Online (Sandbox Code Playgroud)\n\n

函数\xe2\x80\x99s 的名称仍然是fooBar,但该函数仅绑定到fooBar函数本身内部的变量,而不是外部的变量。事实上,它确实使函数可以在其作用域内访问,而无需引用外部作用域中的变量,这意味着命名它有两个原因:

\n\n
    \n
  • 无论外部函数中的代码如何,都能够引用自身内部的函数!

    \n\n

    这可以返回外部函数想要的任何内容:

    \n\n
    function fooBar() {\n    return fooBar.toString();\n}\n\nvar baz = fooBar;\nfooBar = 5;\nbaz(); // "5"\n
    Run Code Online (Sandbox Code Playgroud)\n\n

    这始终是一致的:

    \n\n
    var fooBar = function fooBar() {\n    return fooBar.toString();\n};\n\nvar baz = fooBar;\nfooBar = 5;\nbaz(); // "function fooBar() { \xe2\x80\xa6"\n
    Run Code Online (Sandbox Code Playgroud)
  • \n
  • 是的,对于更详细的堆栈跟踪:

    \n\n
    function trace(func) {\n    try {\n        func();\n    } catch (error) {\n        console.log(error.stack);\n    }\n}\n\ntrace(function () {\n    throw new Error("Bad thing");\n});\n/*\nError: Bad thing\n    at /home/ryan/test.js:10:18\n    at trace (/home/ryan/test.js:3:16)\n    at Object.<anonymous> (/home/ryan/test.js:9:8)\n    at Module._compile (module.js:410:26)\n    at Object.Module._extensions..js (module.js:428:10)\n    at Module.load (module.js:335:32)\n    at Function.Module._load (module.js:290:12)\n    at Function.Module.runMain (module.js:451:10)\n    at startup (node.js:123:18)\n    at node.js:866:3\n*/\n\ntrace(function descriptiveName() {\n    throw new Error("Bad thing");\n});\n/*\nError: Bad thing\n    at descriptiveName (/home/ryan/test.js:14:18)\n    at trace (/home/ryan/test.js:3:16)\n    at Object.<anonymous> (/home/ryan/test.js:13:8)\n    at Module._compile (module.js:410:26)\n    at Object.Module._extensions..js (module.js:428:10)\n    at Module.load (module.js:335:32)\n    at Function.Module._load (module.js:290:12)\n    at Function.Module.runMain (module.js:451:10)\n    at startup (node.js:123:18)\n    at node.js:866:3\n*/\n
    Run Code Online (Sandbox Code Playgroud)\n\n

    (此处为 Node.js 图片。)注意descriptiveName第二个堆栈跟踪顶部的 。当您的异步回调、事件、传递的对象方法等稍微复杂的系统时,这尤其方便。

  • \n
\n