Вложенная функция 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;
}

Как можно определить функцию в другой функции? Можем ли мы вызвать pad2 () извне моей функции ()?

Пожалуйста, осветите это. Спасибо


13
функции могут быть созданы внутри функций. Это совершенно верно.
0x499602D2 03

Ответы:


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функции.

в качестве другого примера:

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

FizzФункция предназначена как конструктор , так что при запуске он назначает buzzфункцию для вновь созданного объекта.


Что такое window.baz = baz? Почему эта линия m? Ke baz доступна?
Ziyang Zhang

@ZiyangZhang, абзац после этого блока кода содержит объяснение, была ли какая-то часть неясной?
zzzzBov

35

Это называется закрытием .

По сути, функция, определенная в другой функции, доступна только в этой функции. Но может быть передан в результате и тогда этот результат может быть вызван.

Это очень мощная функция. Вы можете увидеть больше объяснений здесь:

javascript_closures_for_dummies.html зеркало на Archive.org


13
function x() {}

эквивалентно (или очень похоже) на

var x = function() {}

если я не ошибаюсь.

Так что ничего смешного не происходит.


8
Первый синтаксис будет перемещен в начало документа. так что можно вызвать функцию «x» до инициализации функции.
Tom

10
Первый синтаксис также даст вам гораздо более удобную трассировку стека с именованными функциями, второй вызовет у вас головную боль
TheZ

@TheZ Я думаю, что Chrome недавно добавил вывод имени функции для отладки, поэтому у вас не будет такой же головной боли, как раньше в общем случае.
jinglesthula

@jinglesthula Да!
Некоторое

10

Создание экземпляров функций разрешено внутри и вне функций. Внутри этих функций, как и в переменных, вложенные функции являются локальными и поэтому не могут быть получены извне.

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

fooманипулирует barвнутри себя. barнельзя касаться из внешней области, если она не определена во внешней области.

Так что это не сработает:

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

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

4

Когда вы объявляете функцию внутри функции, внутренние функции доступны только в той области, в которой они объявлены, или, в вашем случае, pad2могут быть вызваны только в dmyобласти.

Все переменные, существующие в dmy, видны в pad2, но не бывает наоборот: D


2

В Javascript (и во многих языках) совершенно нормально иметь функции внутри функций.

Найдите время, чтобы выучить язык, не используйте его на том основании, что он похож на то, что вы уже знаете. Я бы посоветовал посмотреть серию презентаций YUI на Javascript Дугласа Крокфорда с особым акцентом на Act III: Function the Ultimate (ссылка на загрузку видео, слайды и стенограмму)


0

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

Выдает ошибку. Поскольку barопределено внутри foo, barбудет доступно только внутри foo.
Для использования barнужно запустить его внутрь foo.

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.