JavaScript'teki artış (“++”) ve azaltma (“-”) operatörlerinden neden kaçınmalısınız?


357

Jslint aracı için ipuçlarından biri:

++ ve -
++ (artış) ve - (azalma) operatörlerinin aşırı hileyi teşvik ederek kötü koda katkıda bulunduğu bilinmektedir. Virüslere ve diğer güvenlik tehditlerine olanak tanıyan hatalı mimariden sonra ikinci sıradalar. Bu operatörlerin kullanımını yasaklayan bir artı seçenek vardır.

PHP yapıları gibi $foo[$bar++]kolayca off-by-one hataları ile sonuçlanabilir biliyorum , ama bir while( a < 10 ) do { /* foo */ a++; }veya daha döngü kontrol etmek için daha iyi bir yol anlayamadık for (var i=0; i<10; i++) { /* foo */ }.

Jslint onları " ++" ve " --" sözdiziminden yoksun ya da farklı şekilde ele aldığı için benzer diller olduğundan mi yoksa eksik olabileceğim " ++" ve " --" 'den kaçınmanın başka mantıkları mı var?


59
Bu nedenle, dizi [++ dizini] yerine dizi [index = index + 1] yapmalıdır (öncekine bile izin verilirse!). Ne büyük bir yük.
Lawrence Dol

34
Crockford dizin = dizin + 1 yapmak görmedim. İndeks + = 1 yaptığını gördüm. Bence bu makul bir alternatif. Ve adım 1 dışında bir şeye değiştirmek istediğinizde güzel
Nosredna

124
Şahsen ben Crockford'un büyük bir hayranı değilim. Kodunda bir hataya neden olan herhangi bir şeyi kötülük olarak görüyor gibi görünüyor.
Paolo Bergantino

38
JavaScript'te her hatayı biraz kötülük olarak görmelisiniz, çünkü resmi bir belge yoktur veya bir sertifika sağlayıcısı yoktur ve JS'yi üniversitede düzgün bir şekilde öğrenmezsiniz. Crockford ve Firebug, JavaScript eğitiminde bu delikleri doldurdular.
stevek

40
++hatalara neden olmaz. Kullanılması ++"zor" yollarla olabilir birden fazla kişinin kodların sürdürüldüğünü, özellikle böcek yol, ama bu operatör ile ilgili bir sorun değil, programcı ile ilgili bir sorun var. JS'yi üniversitede öğrenmedim (çünkü henüz yoktu), ama ne olmuş? Tabii ki ++ilk olan C'yi yaptım , ama bu da bir "öyleyse ne?" Belirli bir dili öğrenmek için üniversiteye gitmedim, herhangi bir dile uygulayabileceğim iyi programlama uygulamaları öğrenmeye gittim .
nnnnnn

Yanıtlar:


408

Benim görüşüm her zaman olduğu gibi ++ ve - tek başına tek bir satırda kullanmaktır:

i++;
array[i] = foo;

onun yerine

array[++i] = foo;

Bunun dışındaki herhangi bir şey bazı programcılar için kafa karıştırıcı olabilir ve bence buna değmez. Çünkü döngüler bir istisnadır, çünkü artım operatörünün kullanımı deyimseldir ve bu nedenle daima açıktır.


3
Evet, ben de öyle yapıyorum. Yanlış gitmek zor ve başkalarının ne yaptığını anlaması daha kolay.
Nosredna

65
Bu, sorunun ve karışıklığımın özünü oluşturuyor gibi görünüyor. Tek başına kullanılır, i ++; kristal berraklığındadır. Bu temel ifadenin çevresine başka bir kod eklediğiniz anda, okunabilirlik ve netlik bozulmaya başlar.
artlung

2
Kabul et, ama sadece JavaScript ile ilgili değil
Tobias

5
C mi yoksa C ++ mı yazdığınızı söylemezsiniz. iDeğişkenin daha sonra bileşik bir sınıf olması durumunda, C ++ 'da önek artış operatörünü kullanmalısınız, bu durumda gereksiz bir şekilde geçici bir nesne oluşturursunuz. Postfix operatörünün estetik açıdan daha hoş olduğunu düşünüyorum.
mc0e

2
1 satırlı sürümü tercih ederim. Bir yığın işlemini hatırlatır. push dizi [++ i] = foo, pop bar = dizi [i--]. (Ancak 0 tabanlı dizilerle dizi [i ++] = foo ve bar = dizi [- i] daha iyi görünür). Başka bir şey, birisi i ++ arasında ekstra kod ekledi eğer nefret ediyorum; ve dizi [i] = foo;.
Florian F

257

Açıkçası bu tavsiyeyle kafam karıştı. Bir parçam, javascript kodlayıcıları ile deneyim eksikliği (algılanan veya gerçek) ile ilgisi olup olmadığını merak ediyor.

Birisi nasıl sadece bazı örnek kod "hack" nasıl + ve - ile masum bir hata yapabilir görebilirsiniz, ama deneyimli bir profesyonel neden onları önlemek olacağını görmüyorum.


7
Pointyi nokta Jon B. Bu yüzden beni rahatsýz etti. Crockford bir kariyer programcısıdır (onlarca yıllık), on yıllar boyunca birçok dilde konuşur ve kurulduğundan bu yana temelde JavaScript ile çalışır. Onun tavsiyesinin "Tembel ve dikkatsiz deneyimsiz hackerlardan" geldiğini sanmıyorum - bu yüzden nereden geldiğini anlamaya çalışıyorum.
artlung

14
@artlung Belki "Tembel ve dikkatsiz deneyimsiz bir hacker" ile ilgili daha fazla muhtemelen bu kod ile karışıklık olacak, ve ben onu karıştırmak istemiyorum.
Chris Cudmore

9
Cevabınıza tamamen katılmıyorum. Bence 'Kullanmak için yeterince deneyimli miyim?' - ama 'Daha net mi, değil mi?' Eğer bir for döngüsü içinde veya tek başına, net bir şekilde açıksa - herkes bunu zarar vermeden anlayacaktır. Sorun ++, wich ++ x içinde daha kıvrımlı bir ifadeye konulduğunda , x ++ 'dan farklı olduğu için okunması kolay olmayan bir şeyle sonuçlanır. Crockford'un fikri 'yapabilir miyim?' 'hataları nasıl önleyebilirim?'
ArtoAle

1
Netliğin sizin için kompaktlıktan daha önemli olduğu kişisel tercih. Bu, kodu anlayacak kadar deneyimli olmanın ötesine geçer. Değerinden daha fazla sorun olduğu örnekler için diğer cevaplara bakın.
Frug

1
Tamamen katılıyorum. Neden dilin bir bölümünü kullanmıyorsunuz? Hem artım sonrası hem de artım ve düşüşleri kullanmak için iyi nedenler buluyorum. Bana göre böyle bir çizgi açık ve özlü ... if (--imagesLoading === 0) start (); Kodunuzun belirsiz olduğunu düşünüyorsanız, yorumları kullanın!
xtempore

69

C'de bir şey yapmanın bir tarihi vardır:

while (*a++ = *b++);

bir dizeyi kopyalamak için belki de bahsettiği aşırı hileliğin kaynağı budur.

Ve her zaman ne olduğu sorusu vardır

++i = i++;

veya

i = i++ + ++i;

aslında. Bazı dillerde tanımlanmıştır ve diğerlerinde ne olacağının garantisi yoktur.

Bu örnekler bir yana, artmak için kullanılan bir for döngüsünden daha deyimsel bir şey olduğunu sanmıyorum ++. Bazı durumlarda, bir foreach döngüsüyle veya farklı bir durumu kontrol eden bir while döngüsüyle kurtulabilirsiniz. Ancak, arttırma kullanmaktan kaçınmak için kodunuzu bükmek saçma.


105
i = i ++ + ++ i; gözlerimi biraz
incittirdi

3
Benim de. Hepsi aynı değişken olmasa bile, x = a ++ + ++ b; - bu kombinasyon anında x, a ve b'yi kafamda tutmayı zorlaştırır. şimdi, her biri ayrı satırlarda ayrı ifadeler olsaydı, - a ++ 'da olduğu gibi; ++ B; x = a + b; ilk bakışta anlamak daha kolay olurdu.
artlung

10
Ne yazık ki, (a ++; b ++; x = a = b) (a ++ + ++ b) ile aynı değer değildir.
Thomas L Holaday

8
@Marius: x = a+++b-> x = (a++)+b-> x = a + b; a++. Belirteç açgözlü.
Callum Rogers

14
Ek iş güvenliği için, son örneğinizdeki boşlukları kaldırın.
mc0e

48

JavaScript İyi Parçalar'ı okursanız, Crockford'un bir for döngüsünde i ++ yerine ikisinin i + = 1 (i = i + 1 değil) olduğunu görürsünüz . Bu oldukça temiz ve okunabilir ve "zor" bir şeye dönüşme olasılığı daha düşük.

Crockford AUTOINCREMENT izin vermeme ve bir autodecrement yapılan seçeneği jslint içinde. Tavsiyeye uyup uymayacağınızı siz seçersiniz.

Kendi kişisel kuralım, otomatik azaltma veya otomatik azaltma ile birlikte hiçbir şey yapmamaktır.

Ben C deneyim yıllardan ben basit kullanımı devam ederseniz ben arabellek taşması (veya sınırları dışında dizi dizini) alamadım öğrendim. Ama ben aynı ifadede başka şeyler yapmak "aşırı zor" uygulama içine düşersem arabellek taşması olduğunu keşfettim.

Yani, kendi kurallar için, bir for döngüsünde artış olarak i ++ kullanımı gayet iyi.


"Plusplus" seçeneği hakkında mükemmel bir nokta, sadece bir seçenek olmak. Sizinkine ve diğer cevaplara dayanarak bence ++ kendiliğinden veya bir for-loop'un kendi içinde kafa karıştırıcı olmadığı hissine kapılıyorum. Bu ++ ifadesini başka bir ifadede birleştirdiğinizde, bağlam içinde okumak ve anlamak daha zor hale gelir.
artlung

6
herkes arabellek taşar. OpenSSH ve açık kaynak kodlarıyla ve birden fazla revizyon komedisiyle bile
Eric

11
@Eric Beş yaşındaki yorumunuzu tekrar gözden geçirin: oh, ne kadar haklıydınız!
wchargin

27

Bir döngüde zararsızdır, ancak bir atama ifadesinde beklenmedik sonuçlara yol açabilir:

var x = 5;
var y = x++; // y is now 5 and x is 6
var z = ++x; // z is now 7 and x is 7

Değişken ve operatör arasındaki boşluk da beklenmedik sonuçlara yol açabilir:

a = b = c = 1; a ++ ; b -- ; c; console.log('a:', a, 'b:', b, 'c:', c)

Bir kapanışta, beklenmedik sonuçlar da bir sorun olabilir:

var foobar = function(i){var count = count || i; return function(){return count++;}}

baz = foobar(1);
baz(); //1
baz(); //2


var alphabeta = function(i){var count = count || i; return function(){return ++count;}}

omega = alphabeta(1);
omega(); //2
omega(); //3

Ve yeni satırdan sonra otomatik noktalı virgül eklemeyi tetikler:

var foo = 1, bar = 2, baz = 3, alpha = 4, beta = 5, delta = alpha
++beta; //delta is 4, alpha is 4, beta is 6

preincrement / postincrement karışıklığı, teşhis edilmesi son derece zor olan tek tek hatalar üretebilir. Neyse ki, onlar da gereksizdir. Bir değişkene 1 eklemenin daha iyi yolları vardır.

Referanslar


13
Ancak operatörü anlarsanız "beklenmedik" değildirler. Şimdiye kullanmıyor gibi ==arasındaki farkı anlayamıyorum çünkü ==ve ===.
greg84

1
Kesinlikle. Yanlış varsayımları çürüten bir C # sorusu var.
Paul Sweatte

Bence Crockford'un amacı, çoğu programcının yaptıklarını düşündüklerinde bile operatörü tam olarak anlamadığıdır; bu nedenle, bunları kullanma tehlikesi vardır, çünkü yanlış anlama potansiyeli yüksektir. @ Paul'un insanların önek ve düzeltme sonrası operatörlerinin gerçekte nasıl çalıştığını yanlış anladıkları iddiasını destekleyen yanlış varsayımlar hakkındaki yorumuna bakın. Bununla birlikte, onları kullanmayı sevdiğimi itiraf ediyorum, ancak başkaları uğruna kullanımlarını deyimsel vakalarla sınırlamaya çalışıyorum (bkz. Cdmckay'ın cevabı ).
gfullam

Whitespace bağlantınız kopmuş gibi görünüyor.
Ruslan

"Beyaz alan" örneğinizin zor tarafı nedir? Basit bir çıktı alıyorum a: 2 b: 0 c: 1. İlk örnekte ("atama ifadesi") de garip veya beklenmedik bir şey görmüyorum.
Ken Williams

17

Aşağıdaki kodu düşünün

    int a[10];
    a[0] = 0;
    a[1] = 0;
    a[2] = 0;
    a[3] = 0;
    int i = 0;
    a[i++] = i++;
    a[i++] = i++;
    a[i++] = i++;

i ++ iki kez değerlendirildiğinden çıktı (vs2005 hata ayıklayıcısından)

    [0] 0   int
    [1] 0   int
    [2] 2   int
    [3] 0   int
    [4] 4   int

Şimdi aşağıdaki kodu göz önünde bulundurun:

    int a[10];
    a[0] = 0;
    a[1] = 0;
    a[2] = 0;
    a[3] = 0;
    int i = 0;
    a[++i] = ++i;
    a[++i] = ++i;
    a[++i] = ++i;

Çıktının aynı olduğuna dikkat edin. Şimdi ++ i ve i ++ 'ın aynı olduğunu düşünebilirsiniz. Onlar değil

    [0] 0   int
    [1] 0   int
    [2] 2   int
    [3] 0   int
    [4] 4   int

Son olarak bu kodu düşünün

    int a[10];
    a[0] = 0;
    a[1] = 0;
    a[2] = 0;
    a[3] = 0;
    int i = 0;
    a[++i] = i++;
    a[++i] = i++;
    a[++i] = i++;

Çıktı şimdi:

    [0] 0   int
    [1] 1   int
    [2] 0   int
    [3] 3   int
    [4] 0   int
    [5] 5   int

Yani aynı değiller, her ikisi de karıştırmak o kadar sezgisel davranışla sonuçlanmaz. Döngüler için ++ ile tamam olduğunu düşünüyorum, ancak aynı satırda veya aynı talimatta birden fazla ++ sembolü olduğunda dikkat edin


3
Bu deneyi yaptığınız için teşekkürler. Özellikle "basit görünümlü" kod, ama beynimin çok çabuk tutunması zorlaşıyor. Kesinlikle "zor" kategorisine girer.
artlung

28
İlk örnekten sonra durdum. "Aşağıdaki kodu düşünün" dediniz. Hayır, kimse bu kodu yazmaz. Bir dil kurumu değil, kimin kusurlu olduğunu yazan salak.
Sam Harwell

4
İki farklı kod parçasının farklı çıktılar ürettiğini ve bunun kötü olduğunu kanıtladığını gösterdiniz mi?
nickf

7
sonuç "aynı satırda veya aynı komutta birden fazla ++ sembolünüz olduğunda dikkat edin". Okuduğunu sanmıyorum
Eric

1
"i ++ iki kez değerlendirildiğinden beri" - yanlış! Bir değişkeni sıra noktaları arasında iki kez değiştirmek ve bunu kullanmak C ++ 'da geçersizdir ve tanımlanmamış davranışa yol açar. Böylece derleyici istediği her şeyi yapabilir. Burada sunulan sonuçlar derleyici uygulamasının kazaradır.
tbleher

16

Artış ve eksiltme operatörlerinin "öncesi" ve "sonrası" doğası, bunlara aşina olmayanlar için kafa karıştırıcı olabilir; bu onların zor olabilmelerinin bir yoludur.


29
Kabul; Ancak deneyimli bir profesyonel olmalıdır karıştırılmamalıdır.
Nate

1
Bence bu, her şeyi statik veya küresel yapmaktan kaçınmak için rehberliğe benzer. Bir programlama yapısı olarak bununla ilgili yanlış bir şey yoktur, ancak cahil aşırı kullanım kötü koda yol açabilir.
Joel Martinez

7
Soru, iyi bir programcının mantık yoluyla "kendi yolunda çalışıp çalışamayacağı" değildir - iyi kod ideal olarak anlaşılması için herhangi bir çalışma gerektirmez. Bence McWafflestix'in amacı, kısa bir incelemeden sonra iki hafta veya iki yıl içinde hata eklemeye yol açabilecek bir kod yazmamanızdır. Tam olarak anlamadığım bir rutine kod eklemekten suçlu olduğumu biliyorum :)
Mike

1
@Mike: yah, operatörlerin kodun orijinal yazarı veya sonraki bakıcılar için zor olup olmayacağını nasıl belirtmediğime dikkat edin. Genel olarak, orijinal kodlayıcıların aşina olmadıkları / rahat etmedikleri yapıları kullanmadığını varsaymaya çalışıyoruz (ne yazık ki, bu genellikle yanlış bir varsayımdır); bununla birlikte, bu aşinalık kesinlikle koruyucuları kapsamaz (ve yukarıda parantez içinde belirtildiği gibi, orignal yazara bile uzanmayabilir).
Paul Sonier

Kodumu diğer programcıların okuması için yazmaya çalışıyorum , ama yeni başlayanların okuması için yazmaya çalışmıyorum .
Luke H

16

Benim görüşüme göre, "Açık, her zaman örtük olmaktan iyidir." Çünkü bir noktada, bu artış ifadesiyle kafanız karışabilir y+ = x++ + ++y. İyi bir programcı kodunu her zaman daha okunaklı yapar.


1
X ++ veya ++ y'de örtük bir şey yoktur.
Florian F

1
Bu okunabilir kod şey zor ... Bence kodunuzun ne kadar basit olması gerektiğine dair bir temel çizgi var ve biz -bir topluluk olarak- biraz gelişmeli ve bir satır gibi okunabilir olmayanları okuyabilmeliyiz daha fazla şeyin girmesine izin vermek için yuvalanmış üçlülerle ...
Hamza Ouaghad

14

++ veya - 'dan kaçınmanın en önemli mantığı, operatörlerin değerleri döndürmesi ve aynı zamanda yan etkilere neden olması, kod hakkında akıl yürütmeyi zorlaştırmasıdır.

Verimlilik için şunu tercih ederim:

  • ++ i kullanmayan dönüş değeri (hiçbir geçici)
  • i ++ kullanılarak dönüş değeri (bir boru hattı durak)

Bay Crockford hayranıyım, ama bu durumda katılmıyorum. ++iayrıştırılacak metinden% 25 daha az i+=1 ve tartışmasız daha nettir.


13

Douglas Crockford'un bu konudaki videosunu izledim ve arttırma ve eksiltme kullanmamaya ilişkin açıklaması

  1. Geçmişte diğer dillerde dizilerin sınırlarını kırmak ve tüm kötülük ve davranış biçimlerine neden olmak için kullanılmıştır.
  2. Daha kafa karıştırıcı ve deneyimsiz JS geliştiricileri tam olarak ne yaptığını bilmiyorlar.

Öncelikle JavaScript'teki diziler dinamik olarak boyutlandırılmıştır ve bu yüzden yanlışsam beni affet, bir dizinin sınırlarını kırmak ve JavaScript'te bu yöntem kullanılarak erişilmemesi gereken verilere erişmek mümkün değildir.

İkincisi, karmaşık olan şeylerden kaçınmalıyız, elbette sorun bu tesise sahip olmamız değil, sorun şu ki, JavaScript yaptıklarını iddia eden ancak bu operatörlerin nasıl çalıştığını bilmeyen geliştiriciler var mı? Yeterince basit. değeri ++, bana geçerli değeri ver ve ifade bir tane ekledikten sonra, ++ değeri, bana vermeden önce değeri artır.

Bir ++ + ++ b gibi ifadeler, yukarıdakileri hatırlarsanız kolayca çalışabilirsiniz.

var a = 1, b = 1, c;
c = a ++ + ++ b;
// c = 1 + 2 = 3; 
// a = 2 (equals two after the expression is finished);
// b = 2;

Sanırım sadece kodu kimin okuması gerektiğini hatırlamanız gerekiyor, eğer JS'yi dışarıda bilen bir ekibiniz varsa endişelenmenize gerek yok. Değilse, yorum yapın, farklı yazın, vb. Yapmanız gerekeni yapın. Artış ve azalmanın doğası gereği kötü olduğunu veya hata yaratan veya güvenlik açığı oluşturduğunu düşünmüyorum, belki de kitlenize bağlı olarak daha az okunabilir.

Btw, sanırım Douglas Crockford zaten bir efsane, ama bence hak etmeyen bir operatör üzerinde çok korkuttu.

Yine de yanlış olduğu kanıtlanmış olarak yaşıyorum ...


10

Başka bir örnek, artmış değerin basit geri dönüşüyle ​​diğerlerinden daha basit:

function testIncrement1(x) {
    return x++;
}

function testIncrement2(x) {
    return ++x;
}

function testIncrement3(x) {
    return x += 1;
}

console.log(testIncrement1(0)); // 0
console.log(testIncrement2(0)); // 1
console.log(testIncrement3(0)); // 1

Gördüğünüz gibi, bu operatörün sonucu etkilemesini istiyorsanız, dönüş ifadesinde hiçbir artım / azalma kullanılmamalıdır. Ancak getiri, artış / azalma sonrası operatörlerini "yakalamaz":

function closureIncrementTest() {
    var x = 0;

    function postIncrementX() {
        return x++;
    }

    var y = postIncrementX();

    console.log(x); // 1
}

İşlevinizden yalnızca biri parametre olarak x alır
Calimero100582

8

Programcıların kullandıkları dilde yetkin olmaları gerektiğini düşünüyorum; açıkça kullanın; ve iyi kullanın. Ben yok yapay kullandıkları dili sakat gerektiğini düşünüyorum. Deneyimden konuşuyorum. Bir zamanlar ELSE kullanmadıkları bir Cobol mağazasının hemen yanında çalıştım, çünkü 'çok karmaşıktı'. Reductio ad absurdam.


@downvoter Büyüleyici. Programcıların bu dilde yetkin olması gerektiğini düşünmüyor musunuz? Dili yapay olarak sakatlamaları gerektiğini mi düşünüyorsun ? Hangisi? Burada üçüncü bir seçenek yok.
Lorne Marquis

1
ve bu COBOL örneği için bir oylama, kodlamaya girmeden önce COBOL'un çoğunlukla öldüğünü daha da sevindiriyor
Mark K Cowan

1
@MarkCowan Nedenini göremiyorum. Demek istediğim, dil değil, keyfi kısıtlama hakkında. Anekdot, Cobol ile ilgili yanlış bir şey göstermez. Ölmek için gereken şey programlama dükkanıydı ve öyle oldu. Herhangi bir büyük bankanın bağırsaklarını ziyaret edin ve Cobol'un canlı ve iyi olduğunu göreceksiniz.
Lorne Marquis

2

Varolan cevapların bazılarında belirtildiği gibi (rahatsız edici bir şekilde yorum yapamıyorum), sorun x ++ ++ x'in farklı değerlere (artıştan önce vs sonra) değer vermesi, ki bu açık değil ve çok kafa karıştırıcı olabilir - Eğer bu değer kullanılır. cdmckay, arttırma operatörünün kullanılmasına izin vermeyi oldukça akıllıca önerir, ancak yalnızca döndürülen değerin, örneğin kendi satırında kullanılmayacağı bir şekilde. Ben de bir for döngüsü içinde standart kullanımı (ancak yalnızca dönüş değeri kullanılmayan üçüncü deyim) içerir. Başka bir örnek düşünemiyorum. Kendimi "yanmış" olduktan sonra, aynı kılavuzu diğer diller için de tavsiye ederim.

Bu aşırı katılığın birçok JS programcısının deneyimsiz olmasından kaynaklandığı iddiasına katılmıyorum. Bu, "aşırı zekice" programcıların tipik yazı tipidir ve daha geleneksel dillerde ve bu dillerde arka planı olan JS geliştiricileri ile çok daha yaygın olduğuna eminim.


1
Cevap için teşekkürler. Yorum yapmak için 50 veya daha iyi bir itibar değerine ihtiyacınız olacaktır. Bkz. Stackoverflow.com/faq
artlung

1
@artlung: Bunun ve arkasındaki mantığın farkındayım. Sadece sinir bozucu olduğunu söylüyordum :)
Privman'ın yakınında

2

Tecrübelerime göre, ++ i veya i ++, operatörün nasıl çalıştığını ilk öğrenmenin dışında hiçbir zaman karışıklığa neden olmamıştır. Operatörleri kullanabileceğiniz dillerde öğretilen herhangi bir lise veya kolej kursu tarafından verilen döngüler ve döngüler için en temel olanı esastır. Şahsen ben ayrı bir satırda bir ++ olmak ile bir şey daha iyi bakmak ve okumak için aşağıdaki gibi bir şey yapıyor bulmak.

while ( a < 10 ){
    array[a++] = val
}

Sonunda bir stil tercihi ve daha fazla bir şey değil, daha önemli olan, kodunuzda bunu yaptığınızda tutarlı kalmanız, böylece aynı kod üzerinde çalışan diğerlerinin takip edebilmesi ve aynı işlevselliği farklı şekillerde işlemek zorunda kalmamasıdır. .

Ayrıca, Crockford, okumak için --i veya i'den daha zor bulduğum i- = 1 kullanıyor gibi görünüyor.


2

İki sentim, iki durumda kaçınılması gerektiğidir:

1) Birçok satırda kullanılan bir değişkeniniz varsa ve bunu kullanan ilk deyimde (veya ortada en son, hatta daha da kötüsü) artırıp / azalttığınızda:

// It's Java, but applies to Js too
vi = list.get ( ++i );
vi1 = list.get ( i + 1 )
out.println ( "Processing values: " + vi + ", " + vi1 )
if ( i < list.size () - 1 ) ...

Bunun gibi örneklerde, değişkenin otomatik olarak artırıldığını / azaltıldığını veya hatta ilk ifadenin kaldırıldığını kolayca özleyebilirsiniz. Başka bir deyişle, yalnızca çok kısa bloklarda veya değişkenin blokta birkaç yakın ifadede göründüğü yerlerde kullanın.

2) Birden fazla ++ ve - aynı ifadede yaklaşık aynı değişken olması durumunda. Böyle durumlarda ne olduğunu hatırlamak çok zor:

result = ( ++x - --x ) * x++;

Sınavlar ve profesyonel testler yukarıdaki gibi örnekler soruyor ve gerçekten bunlardan biri hakkında belge ararken bu soruyu tökezledim, ancak gerçek hayatta tek bir kod satırı hakkında çok fazla düşünmek zorunda kalmamalıyım.


1

Fortran C benzeri bir dil midir? Ne ++ ne de - vardır. İşte size bir döngü yazma nasıl :

     integer i, n, sum

      sum = 0
      do 10 i = 1, n
         sum = sum + i
         write(*,*) 'i =', i
         write(*,*) 'sum =', sum
  10  continue

İndeks elemanı i , döngü boyunca her seferinde dil kuralları tarafından arttırılır. 1'den başka bir şeyle artırmak istiyorsanız, örneğin iki geriye doğru sayın, sözdizimi ...

      integer i

      do 20 i = 10, 1, -2
         write(*,*) 'i =', i
  20  continue

Python C benzeri mi? Bir dizini artırma gereksinimini atlamak için aralık ve liste kavrayışlarını ve diğer sözdizimlerini kullanır :

print range(10,1,-2) # prints [10,8.6.4.2]
[x*x for x in range(1,10)] # returns [1,4,9,16 ... ]

Dolayısıyla, tam olarak iki alternatifin bu ilk keşfine dayanarak, dil tasarımcıları ++ ve - kullanım durumlarını tahmin ederek ve alternatif bir sözdizimi sağlayarak önleyebilirler.

Fortran ve Python, ++ ve - içeren yordamsal dillerden önemli ölçüde daha az hata mıknatısı mıdır? Kanıtım yok.

Fortran ve Python'un C benzeri olduğunu iddia ediyorum çünkü% 90 doğrulukla akıcı olmayan biriyle tanışmamıştım, gizlenmemiş Fortran veya Python'un niyetini doğru tahmin ediyorlar.


1
Evet, IFortran 1950'lerden, C ise 1970'lerden, bu yüzden Fortran'ın C benzeri olması belki de hayır. Plusplus operatörü gibi bir şey olmayan Python örneği ilginçtir. Veri yapıları üzerinde yineleme Python'da daha açık bir şekilde ele alınır, Python nesne yönelimli JavaScript "farklı" dır. Belki de Crockford'un tavsiyesi, yineleme için daha fazla OO benzeri sözdizimi kullanmakla ilgilidir.
artlung
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.