Yöntemler ve global değişkenler


10

Kodum büyümeye başladığında bir süredir bana musallat olan çok basit bir sorum var.

Parametreler, iç içe geçmiş işlev çağrılarının uzun yollarından geçerken genel değişkenlerle değiştirilmeli mi?

Küresel ortamın bir programın durumunu öngörülemez hale getirebileceğini biliyorum, çünkü birçok işlev paylaşılan değişkenleri değiştirebilir, ancak yine de küresel alan işleri kolaylaştırır.

Kendimi açıklayayım:

functionA(){
   x = something
   functionB(x)
}
functionB(x){
   functionC(x)
}
functionC(x){
   finallyDoSomethingWithX(x)
}
finallyDoSomethingWithX(x){
  x += 1 //Very dummy example ignoring pass by value, not reference.
}

İle ikame edilmiş:

globalX;
functionA(){
   globalX = something
   functionB()
}
...
...
...
finallyDoSomethingWithX(){
   globalX += 1
}

İkinci yolun programlamaya çok fazla özgürlük verdiğini hissediyorum, çünkü parametreler kolayca birikebilir ve ayrıca kodun yeniden kullanılması gerektiğinde bazen çok kısıtlayıcı olabilir, ancak aynı zamanda bir değişkenle ilgili olduğunda fonksiyonun modülerliğini kaybedeceğini hissediyorum. Örneğin, finallyDoSomethingWithXfarklı bir değişkenle çalışmak istediğimde yeniden kullanılabilirliği kaybediyor globalX.

Bu benim başıma geliyor çünkü aslında tasarım desenleri kullanmıyorum çünkü Javascript'te programlama yapıyorum, bu benim için orta projeler için tek bir komut dosyası ile uğraşan bir dil gibi geliyor.

Önerileriniz var mı? desenler? Gerekirse daha spesifik olabilirim.


5
Tipik olarak, değişkenleri çok derinden geçiriyorsanız, sorunu doğru şekilde çözmediniz. Sistemin başka bir yerinde durumu yönlendiren küresel değişkenlere gelince, veba gibi kaçının. Belirli bir noktada yönetmek imkansızdır ve bazı şeyleri rastgele bozarsınız çünkü bazı durumlar rastgele beklemediğiniz bir işlevle mutasyona uğrar.
mgw854

Veba gibi önlemek. Anladım. "Sorunu doğru bir şekilde çözmediniz" hakkında biraz daha ayrıntılı bilgi verebilir misiniz? Genel fikri anlıyorum ama bunu gerçekten anlamak için bir örnek ya da bir şey bulamıyorum.
AFP_555

2
Kendinizi birçok katmanı derinlemesine argümanlar iletirken bulduğunuz yaygın bir çözüm, bir yöntem nesnesi oluşturmaktır : yöntemleri, parametreleri ileten işlevlere karşılık gelen yeni bir sınıfın nesnesi. Parametreler daha sonra nesneye yerel değişkenler haline gelebilir ve yöntemlerinin artık değerler boyunca iletilmesi gerekmez.
Kilian Foth

@KilianFoth Teşekkürler. Cevabı kontrol edebilmem için lütfen biraz kod yazabilir misiniz?
AFP_555

1
JavaScript kodunuzun yapısını diğer dillerde yaptığınız gibi ("gerçek" sınıflar gibi) ele almayı düşünün. Bu ilgili soru üzerine SO hakkında bazı yararlı bağlantılar: stackoverflow.com/questions/927651/…
Ben Cottrell

Yanıtlar:


7

Global değişkenler kullanmayın.

Ayrıca, parametreleri fonksiyon zincirlerinden geçirmeyin!

Bu zor çünkü gerçek bir örnek kullanmıyorsunuz. Ancak normalde daha iyi bir yaklaşım olacaktır.

Diyelim ki çeşitli düşük seviyeli işlevler tarafından kullanılan API'leri çağırmak için kullanmamız gereken bir şifre değişkenimiz var.

Global yaklaşım (psudo code)

var pass;

function multiply(a,b) {
   return apiMultiply(pass,a,b);
}

Parametre geçiş yaklaşımı

function multiply(a,b,pass) {
    return apiMultiply(pass,a,b);
}

Nesne yaklaşımı

class math {
    var api;
    constructor(pass) {
        api = new api(pass);
    }

    function Multiply(a,b) {
        api.Multiply(a,b); //uses pass from constructor
    }
}

Mükemmel. Bu şekilde geçiş global ortamda değildir ve nesnenin niteliklerinden alınabileceğinden, çoklu işlevler için bir parametre değildir. Teşekkürler.
AFP_555

3

Veba gibi globallerden kaçının.

Herhangi bir kod bir genel değiştirebilirsiniz. Eğer A (x) -> B (x) -> C (x) -> ... -> Z (x) zinciriniz varsa ve x'i global bir X'e depolarsanız ve şimdi bir A zinciriniz varsa > B-> C -> ...-> Z, o zaman bu uzun zincirin her adımında veya tamamen bağımsız bir kodda, birisi X'i değiştirebilir. Z'nin kullandığı değer A'nınkinden tamamen farklı olabilir. ile başladı.

Kodunuzun yapması gerekeni yaptığını veya düşündüğünü yaptığını emin olmak istiyorsanız, bu bir kabus.


1
Tamamen katılıyorum. Eğer probleminizi çözmek için globalleri kullanıyorsanız, şimdi iki probleminiz var.
Caleb Mauer
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.