JavaScript嵌套函数


97

我有一段我不明白的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()吗?

请给它一些照明。谢谢


13
可以在函数内部创建函数。那是完全正确的。
0x499602D2 2011年

Answers:


140

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

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

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

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

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

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

作为另一个示例:

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

Fizz函数被设计为构造函数,以便在运行时将buzz函数分配给新创建的对象。


什么是window.baz = baz?为什么此行可用?
张紫阳

@ZiyangZhang,该代码块后面的段落有说明,是否有特定的部分不清楚?
zzzzBov


13
function x() {}

等同于(或非常相似)

var x = function() {}

除非我弄错了。

因此,没有什么可笑的。


8
第一种语法将移至文档的开头。因此可以在功能初始化之前调用函数“ x”。
汤姆(Tom)

10
第一种语法还会使您使用命名函数获得更好的堆栈跟踪,第二种语法会让您头疼
TheZ 2014年

@TheZ我认为Chrome最近在调试中添加了函数名称推断功能,因此在常见情况下您不会像以前那样头痛。
jinglesthula

@jinglesthula是的!Chrome
不久前

10

在函数内部和外部都可以进行函数实例化。在这些函数内部,就像变量一样,嵌套函数是局部的,因此无法从外部范围获得。

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

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

因此,这将不起作用:

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

bar(); // throws error: bar is not defined

4

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

存在的所有变量在dmy中可见pad2,但在:D周围则不会发生


2

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

花时间学习语言,不要以与您已经知道的相似为基础使用它。我建议您观看道格拉斯·克罗克福德(Douglas Crockford)关于Javascript的YUI系列演示,特别关注《第三幕:终极功能》(链接至视频下载,幻灯片和成绩单)


0

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

会抛出错误。由于bar是在内部定义的foobar因此只能在内部访问foo
要使用它,bar您需要在内部运行它foo

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.