Kapatma JavaScript için neden önemlidir?


16

C # 's lambda ifadesi de kapanışlara sahiptir ancak C # toplulukları veya kitapları tarafından nadiren tartışılmaktadır. C # dünyasında olduğundan çok daha fazla JavaScript insanının ve kitabının kapanışları hakkında konuştuğunu görüyorum . Neden?


3
Çünkü JavaScript birinci sınıf işlevsel dil olarak kabul edilir ve C # klasik bir OOP dilidir. Farklı paradigmalar, farklı programlama stilleri.
Raynos

1
Birinci sınıf fonksiyona sahip olmak, dili fonksiyonel bir dil haline getirir. PHP (5.3'ten beri), python veya D birinci sınıf işleve sahiptir. Bunların işlevsel diller olduğunu söyleyebilir misiniz? Kesinlikle hayır, ya da javascript.
deadalnix

1
@deadalnix JavaScript çok paradigmalı bir dildir. Esas olarak prosedürel, fonksiyonel ve prototip OO paradigmasını destekler. Hiçbir şekilde saf işlevsel bir dil değildir, ancak dili dil bükmeden fonksiyonel paradigmada kolayca javascript yazabilirsiniz. Aynı C # ve python söyleyebilirim.
Raynos

3
@deadalnix, Y birleştiricisini tanımlamanızı sağlayan bir dil işlevsel bir dildir. Tanım olarak.
SK-logic

1
@deadalnix: Sanırım bunun neye yaklaştığı , dilin hangi yaklaşımları desteklediği sorusudur . Birinci derece işlevlere büyük ölçüde dayanan birçok JavaScript çerçevesi ve platformu (özellikle node.js ve DOM (olay modeli)) vardır. PHP, aynı programlama stiline izin veren özelliklere sahiptir, ancak standart API'ye veya birçok çerçeveye bakarsanız, bunun gerçekten dilin merkezinde olmadığını görürsünüz.
back2dos

Yanıtlar:


5

Javascript ad alanları gibi bir özelliğe sahip olmadığından ve her türlü küresel nesne ile kolayca karışabilirsiniz.

Bu nedenle, kendi yürütme ortamında bazı kodları izole edebilmek önemlidir. Kapatma bunun için mükemmeldir.

Kapanmanın bu kullanımı, kodları izole etmek ve her şeyi küresel kapsama sokmamak için ad alanlarınız, sınıflarınız vb.Gibi C # gibi bir dilde mantıklı değildir.

Javascript kodu için çok yaygın bir uygulama bunu şöyle yazıyor:

(function(){
    // Some code
})();

Gördüğünüz gibi, bu anonim bir işlev bildirimidir ve hemen ardından yürütülür. Bu nedenle, işlev içinde tanımlanan her şeye dışarıdan erişmek imkansızdır ve küresel kapsamı bozmayacaksınız. Bu işlevin yürütme bağlamı, bazı kodlar, bu bağlamda tanımlanan iç içe işlevler gibi, geri arama veya her türlü iletebildiğiniz sürece canlı kalacaktır.

Javascript, C # 'dan çok farklı bir dildir. Nesne yönelimli değil, prototip yönelimli. Bu, sonunda çok farklı uygulamalara yol açar.

Neyse, kapaklar iyi, bu yüzden onları kullanın, hatta C #!

DÜZENLEME: Bazıları stackoverflow'un sohbeti hakkında konuştuktan sonra, bu anwer'ın kesin olması gerektiğini düşünüyorum.

Örnek koddaki işlev bir kapatma değildir. Ancak, bu işlev yerel değişken ve iç içe işlevleri tanımlayabilir. Bu yerel değişkenleri kullanan tüm iç içe geçmiş işlevler kapanır.

Bu, küresel kapsamı bozmadan bazı işlevleri bir dizi işlev arasında paylaşmak için kullanışlıdır. Javascript'te en sık kullanılan kapak kullanımı budur.

Kapanış, böyle bazı verileri paylaşmaktan çok daha güçlüdür, ancak gerçekçi olalım, çoğu programcı fonksiyonel programlama hakkında bir şey bilmiyor. C # 'da bu tür bir kullanım için sınıf veya bir ad alanı kullanırdınız, ancak JS bu işlevselliği sağlamaz.

Kapatma ile küresel kapsamı korumaktan daha fazlasını yapabilirsiniz, ancak JS kaynak kodunda göreceğiniz şey budur.


9
Bu bir kapanış değil. Yerel kapsam oluşturmak için işlevleri kullanmanın avantajlarını açıklarsınız.
Raynos

2
bir kapatma ancak serbest değişkenler üzerine kapanırsa bir kapatma işlemidir. Ayrıca JavaScript'in nasıl çalıştığını bilmediğimi söylediğin için teşekkür ederim :)
Raynos

2
daha sonra beni acemi olarak arayarak beni baltalamak için başvurmak, JavaScript SO Sohbet odasında gerçek argümanları ortaya koymaktan çekinmeyin . Bu tartışma gerçekten buraya ait değil, ama SO sohbetindeki yanlış düşüncelerinizi mutlu bir şekilde tartışacağım.
Raynos

1
Downvoted. JavaScript bol nesne yönelimlidir. Sadece sınıf temelli değil, ancak bu işlevsellik kolayca yazılır. Birinci sınıf fonksiyonlara sahiptir, ağır olay odaklı paradigmalar için doğal bir uyum sağlamak için kapaklardan yararlanır ve yazarı Brendan Eich'e göre başlıca ilham kaynağı Scheme'dir. İşlevsel bir dilin ne düşündüğünüzden gerçekten emin değilim, ama komik kısım, sınıf temelli kalıtımın, fonksiyonları geçip yeni bağlamlarda uygulayabildiğinizde artık tamamen gerekli değil, bir şekilde kritik olduğunu düşünüyor olmanızdır.
Erik Reppen

2
-1 de. Bu kapanışları tanımlamaz, kapsamı açıklar.
Izkata

12

Muhtemelen JavaScript'in nesne yöneliminin popüler uygulamaları kapanışlara bağlıdır. Basit bir örneğe bakalım:

function counter() {
   var value = 0;
   this.getValue = function() { return value; }
   this.increase = function() { value++; }
}

var myCounter = new counter();
console.log(myCounter.getValue());
myCounter.increase();
console.log(myCounter.getValue());

Yöntemler getValueve increaseaslında değişkeni kapsülleyen kapanışlardır value.


3
-1 "kapanışlara bağlıdır" Bu oldukça özneldir. O değil.
Raynos

Raynos: Özel üyeleri nasıl kapatıp oluşturacağımızı bize göstermeyi umuyor musunuz?
user281377

1
@ammoQ JavaScript'te gizli diye bir şey yoktur. Kastettiğiniz şey "JavaScript klasik OO öykünmesi kapanışlara bağlı olduğu için" idi. JavaScript OO, farklı bir paradigma olan prototiptir. Yine de, "Klasik
OO'yu

1
@keppla "OO kapanışa bağlı" demekti öznel. OO için kapanışa ihtiyacınız yok.
Raynos

2
beni olduğum temsilcisi fahişe olarak açığa ...
user281377

4

Çünkü JavaScript'i 'katlanılabilir' yapan kitaplıkların çoğu bunları kullanıyor.

Sadece üç popüler olan JQuery , Prototype veya MooTools'a bir göz atın . Bu kitaplıkların her biri, eachkoleksiyonları için tercih edilen yineleme yolu olarak bir yineleyici işlevi kullanan bir yöntem sağlar . Bu işlev, dış kapsamdaki değerlere erişirken bir kapatma olacaktır:

[1,2,3].each(function(item) {
   console.log(item);
});

Ve burada bitmiyor: Ajax'ta geri aramalar, Ext.js'de olay işleme, vb. İşlevlerin tümünü alır ve kodunuzu tam olarak bir kez çağrılan 100 işlevli işlevlerle şişirmek istemiyorsanız, kapanışlar yoludur.


1
Neden bir kapanış değil? console.logdış bir kapsamda tanımlanır, consolebir 'serbest değişken' de tanımlanır. Ve aslında, neden farklı bir şey olmayan bir for-loop, kötü bir uygulama?
keppla

@Raynos: Kapatma tanımım 'serbest değişken içeren blok', bu durumu kaybetmez, serbest değişken en üst kapsamda olur. Ancak, benim fikrimi desteklemek için şu yöntemi düşünün: pastie.org/2144689 . Bu neden kötü olmalı?
keppla

Hala küresel veriler üzerinde "kapanış" hile olarak kabul düşünüyorum. Kapsam zincirindeki verilere erişmenin iyi olduğunu kabul ediyorum, bu erişimi en aza indirgemek iyi bir uygulamadır.
Raynos


Dizi yineleyicilerle (forEach, harita, azaltma, vb.) Kapatma olmalarının sıfır nedeni olduğu, tüm durumların doğrudan onlara aktarıldığına dikkat edilmelidir.
Kapanış

3

JavaScript ile "iyi" kodlamanın daha fazla kapanmaya bağlı olduğu diğer cevaplara katılıyorum. Bununla birlikte, buna ek olarak, muhtemelen her bir dilde özelliğin ne kadar süredir devam ettiği sorusudur. JavaScript, ilk uygulamalarından bu yana temelde kapanışlara sahiptir. Öte yandan C #, 3.0'dan beri sadece Visual Studio 2008 ile piyasaya sürüldü.

Çalıştığım birçok C # programcısı hala 2.0 proje üzerinde çalışıyor. 3.0 veya 4.0 sürümlerinde çalışıyor olsalar da, hala 2.0 deyim kullanıyorlar. Kapakları seviyorum; umarım konsept C # geliştiricileri arasında yayıldıkça C # 'da daha çok kullanılırlar.


2

Bunun ana nedeni, C # 'ın statik olarak yazılması ve işlevlerin yalnızca, kapakların kullanışlılığını engelleyen önceden belirlenmiş tek bir ortama erişimi olmasıdır.

Öte yandan, JavaScript'te, kapaklar işlevlerin bir nesne özelliği olarak erişildiğinde ve birinci sınıf nesneler olarak yöntem olarak davranmasını sağlar, ayrıca alt rutinlerin farklı bağlamlarda çalışmasına izin veren farklı ortamlara da enjekte edilebilir.


1
Statik yazmanın bununla ne ilgisi var? Kapaklar diktir.

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.