JavaScript İç içe geçmiş işlevi


97

Javascript için anlamadığım bir kod parçam var:

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;
}

Bir işlev başka bir işlev içinde nasıl tanımlanabilir? () İşlevimin dışından pad2 () 'yi çağırabilir miyiz?

Lütfen üzerine biraz ışık tutun. Teşekkürler


13
işlevler, işlevlerin içinde oluşturulabilir. Bu tamamen geçerli.
0x499602D2

Yanıtlar:


141

Fonksiyonlar, JavaScript'teki başka bir değişken türüdür (elbette bazı nüanslarla birlikte). Başka bir işlev içinde bir işlev oluşturmak, bir değişkenin kapsamını değiştirecek şekilde işlevin kapsamını değiştirir. Bu, özellikle toplam küresel ad alanı kirliliğini azaltmak için kapaklarla kullanım için önemlidir.

Başka bir işlev içinde tanımlanan işlevlere, işlevin dışında erişilebilen bir nesneye eklenmedikçe işlevin dışında erişilemez:

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

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

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

Bu örnekte baz işlevi, foogeçersiz kılındığı için işlev çalıştırıldıktan sonra kullanıma hazır olacaktır window.baz. Bar işlevi, fooişlevin içerdiği kapsamlar dışında herhangi bir bağlamda kullanılamayacaktır .

farklı bir örnek olarak:

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

FizzFonksiyon çalıştırıldığında, bir atar, böylece yapıcı olarak tasarlanmıştır buzzyeni oluşturulan nesneye işlevi.


Window.baz = baz nedir? Bu m? Ke baz satırı neden kullanılabilir?
Ziyang Zhang

@ZiyangZhang, bu kod bloğundan sonraki paragrafta açıklama var, belli olmayan bir kısım var mıydı?
zzzzBov


13
function x() {}

eşdeğerdir (veya çok benzerdir)

var x = function() {}

yanılmıyorsam.

Yani komik bir şey yok.


8
İlk sözdizimi, belgenin başına taşınacaktır. bu nedenle, işlev başlatılmadan önce 'x' işlevini çağırmak mümkündür.
Tom

10
İlk sözdizimi ayrıca adlandırılmış işlevlerle çok daha güzel yığın izleri elde etmenizi sağlar, ikincisi size bir baş ağrısı verir
TheZ

@TheZ Chrome'un kısa süre önce hata ayıklamaya işlev adı çıkarımı eklediğini düşünüyorum, böylece ortak durumda daha önce olduğu gibi aynı baş ağrısını yaşamazsınız.
jinglesthula

@jinglesthula Evet! Chrome bir süre önce bu ad çıkarımını ekledi ve çok beğenildi :)
TheZ

10

İşlev somutlaştırmasına işlevlerin içinde ve dışında izin verilir. Bu işlevlerin içinde, aynı değişkenler gibi, yuvalanmış işlevler yereldir ve bu nedenle dış kapsamdan elde edilemez.

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

foobarkendi içinde manipüle eder. bardış kapsamda tanımlanmadığı sürece dış kapsamdan dokunulamaz.

Yani bu işe yaramayacak:

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

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

4

Bir işlev içinde bir işlevi bildirdiğinizde, iç işlevler yalnızca bildirildikleri kapsamda kullanılabilir veya sizin durumunuzda pad2yalnızca kapsamda çağrılabilir dmy.

İçinde var olan tüm değişkenler içinde dmygörünür pad2, ancak tam tersi olmaz: D


2

Javascript'te (ve birçok dilde) işlevlerin içinde işlevlere sahip olmak tamamen normaldir.

Dili öğrenmek için zaman ayırın, zaten bildiklerinize benzer olduğu için kullanmayın. Douglas Crockford'un Javascript'teki YUI sunum serisini, özellikle Act III: Function the Ultimate'e (video indirme bağlantısı, slaytlar ve transkript bağlantısı) izlemenizi öneririm.


0

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

Bir hata atacak. Yana bariçeride tanımlanır foo, baryalnızca erişilebilir içinde olacaktır foo.
Kullanmak bariçin içeride çalıştırmanız gerekir foo.

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.