108

我得到了一段我只是不明白的 javascript 代码:

function dmy(d) {
    function pad2(n) {
        return (n < 10) ? '0' + n : n;
    }

    return pad2(d.getUTCDate()) + '/' +
       pad2(d.getUTCMonth() + 1) + '/' +
       d.getUTCFullYear();
}

function outerFunc(base) {
    var punc = "!";

    //inner function
    function returnString(ext) {
       return base + ext + punc;
    }

    return returnString;
}

如何在另一个函数中定义一个函数?我们可以从 my() 函数之外调用 pad2() 吗?

请给它一些光。谢谢

4

8 回答 8

151

函数是 JavaScript 中的另一种变量(当然有一些细微差别)。在另一个函数中创建一个函数会改变函数的作用域,就像改变变量的作用域一样。这对于与闭包一起使用以减少总体全局命名空间污染尤其重要。

在另一个函数中定义的函数将无法在函数外部访问,除非它们已附加到函数外部可访问的对象:

function foo(doBar)
{
  function bar()
  {
    console.log( 'bar' );
  }

  function baz()
  {
    console.log( 'baz' );
  }

  window.baz = baz;
  if ( doBar ) bar();
}

在此示例中,baz 函数将在函数运行后可用foo,因为它已被覆盖window.baz。除了包含在函数中的范围之外,bar 函数将不可用于任何上下文foo

作为一个不同的例子:

function Fizz(qux)
{
  this.buzz = function(){
    console.log( qux );
  };
}

Fizz函数被设计为构造函数,以便在运行时将buzz函数分配给新创建的对象。也就是说,你会像这样使用它:

const obj = new Fizz();
obj.buzz();

或更简洁(如果您不需要在调用后保留对象buzz):

new Fizz().buzz();
于 2011-09-03T20:28:18.453 回答
37

它被称为闭包

基本上,在其他函数中定义的函数只能在该函数中访问。但是可以作为结果传递,然后可以调用此结果。

这是一个非常强大的功能。你可以在这里看到更多的解释:

Archive.org 上的 javascript_closures_for_dummies.html 镜像

于 2011-09-03T20:30:25.340 回答
14
function x() {}

等同于(或非常相似)

var x = function() {}

除非我弄错了。

所以没有什么好笑的。

于 2011-09-03T20:24:08.883 回答
10

函数内部和外部都允许函数实例化。在这些函数内部,就像变量一样,嵌套函数是本地的,因此无法从外部范围获取。

function foo() {
    function bar() {
        return 1;
    }
    return bar();
}

foo在自身内部操纵barbar除非在外部范围中定义,否则不能从外部范围触及。

所以这不起作用:

function foo() {
    function bar() {
        return 1;
    }
}

bar(); // throws error: bar is not defined
于 2011-09-03T20:26:51.610 回答
4

当您在函数中声明函数时,内部函数仅在声明它们的范围内可用,或者在您的情况下,pad2只能在dmy范围内调用。

中存在的所有变量都在dmy中可见pad2,但反过来就不会发生:D

于 2011-09-03T20:28:42.690 回答
3

在 JavaScript(和许多语言)中,在函数中包含函数是完全正常的。

花时间学习语言,不要因为它与你已经知道的相似而使用它。我建议观看 Douglas Crockford 关于 JavaScript 的 YUI 演示系列,特别关注第三幕:终极功能(视频下载、幻灯片和脚本的链接)

于 2011-09-03T20:28:14.280 回答
0

function foo() {
  function bar() {
    return 1;
  }
}
bar();

会抛出错误。由于bar是在里面定义的foobar所以只能在里面访问foo
要使用bar你需要在里面运行它foo

function foo() {
  function bar() {
    return 1;
  }
  bar();
}

于 2020-05-17T00:38:30.623 回答
0

嵌套函数可以作为编写相关函数的模块化组的基础,类似于完全面向对象编程(仅限静态类)。

这是这样一组函数的示例,在这种情况下将值转换为 JSON 字符串或将 JSON 字符串转换为值。

请注意内部函数是如何在外部函数内部分组到一个对象中的,以及对象是如何存储到一个组名中的。这是从组外直接可见的唯一名称。要从外部访问任何包含的函数,您只需编写组名、句点,然后是函数名。要从内部访问包含的函数,您可以使用相同的符号或“this”、句点,然后是函数名称。

//--------------------------------------------------------------------//
//      Module J:
//          Convert from and to JSON strings
//--------------------------------------------------------------------//
const J=NewJ();
function NewJ()
    {
    const mod=
        {
        From:(str)=>
            {
            return JSON.parse(str);
            }, // From
        To:(val)=>
            {
            return JSON.stringify(val,null,3);
            } // To
        }; // mod
    return mod;
    } // NewJ

//--------------------------------------------------------------------//
//      End Module J
//--------------------------------------------------------------------//

这是一个测试:

console.log(J.To({A:'a'}));

控制台输出:

{
   "A": "a"
}
于 2021-06-07T23:39:15.867 回答