Mengapa menghindari operator increment (“++”) dan decrement (“-”) di JavaScript?


357

Salah satu tips untuk alat jslint adalah:

++ dan -
The ++ (increment) dan - (decrement) operator telah dikenal berkontribusi pada kode buruk dengan mendorong trickiness yang berlebihan. Mereka adalah yang kedua setelah arsitektur yang salah dalam mengaktifkan virus dan ancaman keamanan lainnya. Ada opsi plusplus yang melarang penggunaan operator ini.

Saya tahu bahwa konstruksi PHP seperti $foo[$bar++]dapat dengan mudah dihasilkan dengan kesalahan satu per satu, tetapi saya tidak dapat menemukan cara yang lebih baik untuk mengontrol loop daripada a while( a < 10 ) do { /* foo */ a++; }atau for (var i=0; i<10; i++) { /* foo */ }.

Apakah jslint menyoroti mereka karena ada beberapa bahasa yang mirip yang tidak memiliki sintaksis " ++" dan " --" atau menanganinya secara berbeda, atau adakah alasan lain untuk menghindari " ++" dan " --" yang mungkin saya lewatkan?


59
Jadi kita harus melakukan larik [indeks = indeks + 1] alih-alih larik [indeks ++] (jika yang pertama bahkan diizinkan!). Apa yang harus dilakukan?
Lawrence Dol

34
Saya belum melihat Crockford do index = index +1. Saya pernah melihatnya melakukan index + = 1. Saya pikir itu alternatif yang masuk akal. Dan itu bagus untuk ketika Anda ingin mengubah langkah untuk sesuatu selain 1.
Nosredna

124
Secara pribadi saya bukan penggemar berat Crockford. Dia tampaknya menganggap segala sesuatu yang pernah menyebabkan bug dalam kode menjadi jahat.
Paolo Bergantino

38
Dalam JavaScript Anda harus menganggap setiap bug sebagai sesuatu yang jahat, karena tidak ada dokumentasi resmi dan tidak ada penyedia sertifikat juga Anda tidak belajar JS dengan benar di Universitas. Crockford dan Firebug telah mengisi lubang-lubang ini dalam pendidikan JavaScript.
stevek

40
++tidak menyebabkan bug. Menggunakan ++cara - cara "rumit" dapat menyebabkan bug, terutama jika lebih dari satu orang mempertahankan basis kode, tapi itu bukan masalah dengan operator, itu masalah dengan programmer. Saya tidak belajar JS di universitas (karena belum ada), tetapi jadi apa? Saya memang melakukan C, yang tentu saja ++lebih dulu, tetapi itu juga mendapat "jadi apa?" Saya tidak pergi ke universitas untuk belajar bahasa tertentu, saya belajar praktik pemrograman yang baik yang bisa saya terapkan pada bahasa apa pun .
nnnnnn

Jawaban:


408

Pandangan saya adalah untuk selalu menggunakan ++ dan - sendiri pada satu baris, seperti pada:

i++;
array[i] = foo;

dari pada

array[++i] = foo;

Apa pun di luar itu dapat membingungkan bagi beberapa programmer dan tidak sepadan dengan pandangan saya. Untuk loop adalah pengecualian, karena penggunaan operator increment bersifat idiomatis dan karenanya selalu jelas.


3
Ya, itulah yang saya lakukan juga. Sulit untuk salah, dan lebih mudah bagi orang lain untuk mengetahui apa yang Anda lakukan.
Nosredna

65
Itu tampaknya menjadi inti dari masalah dan kebingungan saya. Digunakan sendiri, i ++; sejernih kristal. Begitu Anda menambahkan kode lain di sekitar ekspresi dasar itu, keterbacaan dan kejelasan mulai menderita.
artlung

2
Setuju, tapi tidak hanya terkait dengan JavaScript
Tobias

5
Anda tidak mengatakan apakah Anda sedang menulis C atau C ++. Dapat diperdebatkan Anda harus menggunakan operator kenaikan awalan di C ++, jika ivariabel nanti menjadi kelas komposit, dalam hal ini Anda tidak perlu membuat objek sementara. Saya menemukan operator postfix lebih menyenangkan secara estetika.
mc0e

2
Saya lebih suka versi 1-line. Ini mengingatkan pada operasi stack. push adalah array [++ i] = foo, pop adalah bar = array [i--]. (Tetapi dengan array berbasis 0, array [i ++] = foo dan bar = array [- i] terlihat masih lebih baik). Hal lain, saya akan benci jika seseorang menambahkan kode tambahan antara i ++; dan array [i] = foo ;.
Florian F

257

Terus terang saya bingung dengan saran itu. Sebagian dari saya bertanya-tanya apakah itu lebih berkaitan dengan kurangnya pengalaman (dirasakan atau aktual) dengan coders javascript.

Saya dapat melihat bagaimana seseorang hanya "meretas" beberapa kode sampel dapat membuat kesalahan yang salah dengan ++ dan -, tetapi saya tidak melihat mengapa seorang profesional yang berpengalaman akan menghindarinya.


7
Poin bagus Jon B. Itu sebabnya saya sangat terganggu. Crockford adalah seorang programmer karier (bernilai puluhan tahun), fasih berbicara dalam berbagai bahasa selama beberapa dekade, dan bekerja dengan JavaScript pada dasarnya sejak awal. Saya tidak berpikir nasihatnya berasal dari "Saya malas dan kurang perhatian peretas yang tidak berpengalaman" - itulah sebabnya saya mencoba memahami dari mana asalnya.
artlung

14
@artlung Mungkin ini lebih berkaitan dengan "Seorang peretas yang tidak berpengalaman dan malas" mungkin akan mengacaukan kode ini, dan saya tidak ingin membingungkannya.
Chris Cudmore

9
Saya sepenuhnya tidak setuju dengan jawaban Anda. Menurut pendapat saya, ini bukan tentang 'Apakah saya cukup berpengalaman untuk menggunakannya?' - tapi 'Lebih jelas atau tidak?' Jika di dalam for for loop, atau sendirian, itu sangat jelas - semua orang akan mengerti itu tanpa membahayakan. Masalahnya muncul ketika dimasukkan ke ++dalam ekspresi yang lebih berbelit-belit di mana ++ x berbeda dari x ++, sehingga menghasilkan sesuatu yang tidak mudah dibaca. Ide Crockford bukan tentang 'bisakah saya melakukannya?' ini tentang 'bagaimana saya bisa menghindari kesalahan?'
ArtoAle

1
Ini adalah preferensi pribadi pada titik mana kejelasan lebih penting bagi Anda daripada kekompakan. Ini lebih dari cukup berpengalaman untuk memahami kode. Lihat jawaban lain untuk contoh di mana lebih banyak masalah daripada nilainya.
Frug

1
Saya sangat setuju. Mengapa cacat sendiri dengan tidak menggunakan bagian dari bahasa? Saya menemukan alasan yang bagus untuk menggunakan peningkatan dan penurunan post dan pre. Bagi saya, baris seperti ini jelas dan ringkas ... if (--imagesLoading === 0) start (); Jika Anda merasa kode Anda tidak jelas, gunakan komentar!
xtempore

69

Ada sejarah dalam C dalam melakukan hal-hal seperti:

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

untuk menyalin string, mungkin ini adalah sumber tipu daya berlebihan yang dia maksud.

Dan selalu ada pertanyaan tentang apa

++i = i++;

atau

i = i++ + ++i;

sebenarnya. Itu didefinisikan dalam beberapa bahasa, dan dalam bahasa lain tidak ada jaminan apa yang akan terjadi.

Selain contoh-contoh itu, saya tidak berpikir ada sesuatu yang lebih idiomatis daripada untuk loop yang digunakan ++untuk kenaikan. Dalam beberapa kasus Anda bisa lolos dengan loop foreach, atau loop sementara yang memeriksa kondisi yang berbeda. Tetapi memutarbalikkan kode Anda untuk mencoba dan menghindari penggunaan incrementing adalah konyol.


104
i = i ++ + ++ i; membuat mataku sedikit sakit - :)
Hugoware

3
Milik saya juga. Bahkan jika mereka tidak semua variabel yang sama, katakan saya punya x = a ++ + ++ b; - kombinasi itu secara instan membuat x, a dan b lebih sulit untuk dipegang di kepala saya. sekarang, jika masing-masing pernyataan terpisah pada baris yang terpisah, seperti dalam - a ++; ++ b; x = a + b; akan lebih mudah untuk dipahami pada pandangan pertama.
artlung

10
Sayangnya, (a ++; b ++; x = a = b) bukan nilai yang sama dengan (a ++ + ++ b).
Thomas L Holaday

8
@Marius: x = a+++b-> x = (a++)+b-> x = a + b; a++. Tokeniser itu serakah.
Callum Rogers

14
Untuk keselamatan kerja tambahan, hapus spasi di contoh terakhir Anda.
mc0e

48

Jika Anda membaca JavaScript The Good Parts, Anda akan melihat bahwa pengganti Crockford untuk i ++ di dalam for loop adalah i + = 1 (bukan i = i + 1). Itu cukup bersih dan mudah dibaca, dan kecil kemungkinannya berubah menjadi sesuatu yang "rumit".

Crockford menjadikan penonaktifan autoincrement dan autodecrement sebagai opsi di jsLint. Anda memilih untuk mengikuti saran atau tidak.

Aturan pribadi saya adalah untuk tidak melakukan apa pun yang dikombinasikan dengan peningkatan otomatis atau penambahan otomatis.

Saya telah belajar dari pengalaman bertahun-tahun di C bahwa saya tidak mendapatkan buffer overruns (atau indeks array di luar batas) jika saya tetap menggunakannya sederhana. Tetapi saya telah menemukan bahwa saya mendapatkan buffer overruns jika saya jatuh dalam praktik "sangat rumit" melakukan hal-hal lain dalam pernyataan yang sama.

Jadi, untuk aturan saya sendiri, penggunaan i ++ sebagai kenaikan dalam for loop tidak masalah.


Poin luar biasa tentang opsi "plusplus" menjadi pilihan itu. Berdasarkan jawaban Anda dan lainnya, saya rasa saya merasa ++ dengan sendirinya atau for-loop tidak membingungkan. Saat Anda menggabungkan ++ itu ke dalam pernyataan lain, pernyataan Anda menjadi lebih sulit dibaca dan dipahami dalam konteks.
artlung

6
semua orang mendapat buffer overflows. Bahkan OpenSSH dengan sumber terbuka dan berbagai komite revisi
Eric

11
@Eric Meninjau kembali komentar Anda yang berusia lima tahun: oh, betapa benarnya Anda!
wchargin

27

Dalam satu lingkaran itu tidak berbahaya, tetapi dalam pernyataan penugasan itu dapat menyebabkan hasil yang tidak terduga:

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

Spasi putih antara variabel dan operator dapat menyebabkan hasil yang tidak terduga juga:

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

Sebagai penutup, hasil yang tidak terduga juga bisa menjadi masalah:

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

Dan itu memicu penyisipan titik koma otomatis setelah baris baru:

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

kebingungan preincrement / postincrement dapat menghasilkan kesalahan satu per satu yang sangat sulit didiagnosis. Untungnya, mereka juga sama sekali tidak perlu. Ada cara yang lebih baik untuk menambahkan 1 ke variabel.

Referensi


13
Tapi itu bukan "tak terduga" jika Anda memahami operator. Rasanya seperti tidak pernah menggunakan ==karena Anda tidak mengerti perbedaan antara ==dan ===.
greg84

1
Persis. Ada pertanyaan C # yang menghilangkan asumsi salah.
Paul Sweatte

Saya pikir poin Crockford adalah bahwa kebanyakan programmer tidak sepenuhnya "memahami operator" bahkan ketika mereka berpikir mereka melakukannya; karenanya, ada bahaya dalam menggunakannya karena potensi kesalahpahaman tinggi. Lihat komentar @ Paul tentang asumsi salah yang mendukung argumen bahwa orang pada umumnya salah memahami bagaimana operator awalan dan postfix bekerja. Yang mengatakan, saya akui saya suka menggunakannya, tetapi demi orang lain saya mencoba membatasi penggunaannya untuk kasus-kasus idiomatik (lihat jawaban cdmckay ).
gfullam

Tautan spasi putih Anda tampaknya rusak.
Ruslan

Apa yang rumit tentang contoh "spasi putih" Anda? Saya mendapatkan output langsung dari a: 2 b: 0 c: 1. Saya juga tidak melihat sesuatu yang aneh atau tidak terduga dalam contoh pertama ("pernyataan tugas").
Ken Williams

17

Pertimbangkan kode berikut

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

karena i ++ dievaluasi dua kali outputnya (dari vs2005 debugger)

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

Sekarang pertimbangkan kode berikut:

    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;

Perhatikan bahwa outputnya sama. Sekarang Anda mungkin berpikir bahwa ++ i dan i ++ adalah sama. Mereka tidak

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

Akhirnya pertimbangkan kode ini

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

Outputnya sekarang:

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

Jadi mereka tidak sama, mencampur keduanya menghasilkan perilaku yang tidak begitu intuitif. Saya pikir untuk loop ok dengan ++, tapi hati-hati ketika Anda memiliki beberapa simbol ++ pada baris yang sama atau instruksi yang sama


3
Terima kasih telah melakukan percobaan itu. Khususnya kode "tampak sederhana", tetapi sulit bagi otak saya untuk bertahan dengan sangat cepat. Pasti termasuk dalam kategori "rumit".
artlung

28
Saya berhenti setelah contoh pertama. Anda berkata "Pertimbangkan kode berikut". Tidak, tidak ada yang menulis kode itu. Orang bodoh yang menulis bahwa siapa yang cacat, bukan konstruksi bahasa.
Sam Harwell

4
Anda telah menunjukkan bahwa dua bagian kode yang berbeda menghasilkan keluaran yang berbeda dan ini membuktikan bahwa itu buruk?
nickf

7
kesimpulannya adalah "hati-hati ketika Anda memiliki beberapa simbol ++ pada baris yang sama atau instruksi yang sama". Saya tidak berpikir Anda sudah membacanya
Eric

1
"Karena saya ++ dievaluasi dua kali" - salah! Memodifikasi variabel dua kali antara titik urutan dan juga menggunakannya tidak valid di C ++ dan mengarah ke perilaku yang tidak ditentukan. Jadi kompiler dapat melakukan apa pun yang diinginkannya. Hasil yang disajikan di sini adalah kebetulan dari implementasi kompiler.
keras

16

Sifat operator "kenaikan" dan "kenaikan" yang cenderung cenderung membingungkan bagi mereka yang tidak terbiasa dengan mereka; itu salah satu cara di mana mereka bisa rumit.


29
Sepakat; Namun, seorang profesional yang berpengalaman harus tidak bingung.
Nate

1
Saya pikir ini mirip dengan panduan untuk menghindari menjadikan semuanya statis atau global. Tidak ada yang salah dengan itu sebagai konstruksi pemrograman, tetapi terlalu sering menggunakan dapat menyebabkan kode yang buruk.
Joel Martinez

6
Pertanyaannya bukanlah apakah seorang programmer yang baik bisa "bekerja dengan cara mereka" melalui logika - kode yang baik idealnya tidak memerlukan pekerjaan untuk mengerti. Saya pikir poin McWafflestix hanya bahwa Anda tidak harus menulis kode yang pada pemeriksaan singkat dapat menyebabkan penambahan bug dalam dua minggu atau dua tahun. Aku tahu aku sudah bersalah menambahkan kode ke saya rutin tidak sepenuhnya memahami :)
Mike

1
@ Mike: yah, perhatikan bagaimana saya tidak menentukan apakah operator bisa rumit untuk pembuat kode asli atau untuk pengelola nanti. Secara umum, kami mencoba mengasumsikan bahwa pembuat kode asli tidak menggunakan konstruksi yang tidak mereka kenal / nyaman (sayangnya, ini sering merupakan asumsi yang salah); namun demikian, keakraban itu tentu saja tidak meluas ke para pengelola (dan, seperti yang disebutkan di atas, bahkan mungkin tidak meluas ke penulis orignal).
Paul Sonier

Saya mencoba menulis kode untuk dibaca oleh programmer lain, tetapi saya tidak mencoba menulisnya untuk dibaca oleh pemula.
Luke H

16

Dalam pandangan saya, "Eksplisit selalu lebih baik daripada implisit." Karena pada titik tertentu, Anda mungkin bingung dengan pernyataan kenaikan ini y+ = x++ + ++y. Seorang programmer yang baik selalu membuat kodenya lebih mudah dibaca.


1
Tidak ada yang tersirat dalam x ++ atau ++ y.
Florian F

1
Ini kode yang dapat dibaca hal yang rumit ... Saya pikir ada garis dasar untuk bagaimana sederhana kode Anda harus, dan kami -sebagai keharusan komunitas berkembang sedikit dan dapat membaca apa yang sekarang tidak terbaca, seperti satu-liners dengan terner bersarang, untuk memungkinkan lebih banyak hal terjadi.
Hamza Ouaghad

14

Alasan paling penting untuk menghindari ++ atau - adalah bahwa operator mengembalikan nilai dan menyebabkan efek samping pada saat yang sama, membuatnya lebih sulit untuk beralasan tentang kode.

Demi efisiensi, saya lebih suka:

  • ++ i ketika tidak menggunakan nilai kembali (tidak sementara)
  • i ++ saat menggunakan nilai kembali (tidak ada pipeline)

Saya penggemar Mr. Crockford, tetapi dalam hal ini saya harus tidak setuju. ++iadalah 25% lebih sedikit teks untuk diurai daripada i+=1 dan bisa dibilang lebih jelas.


13

Saya sudah menonton video Douglas Crockford tentang ini dan penjelasannya untuk tidak menggunakan kenaikan dan penurunan adalah itu

  1. Ini telah digunakan di masa lalu dalam bahasa lain untuk mematahkan batasan array dan menyebabkan semua perilaku kejahatan dan
  2. Itu lebih membingungkan dan tidak berpengalaman pengembang JS tidak tahu persis apa yang dilakukannya.

Array pertama dalam JavaScript berukuran secara dinamis dan karenanya, maafkan saya jika saya salah, tidak mungkin untuk melanggar batas array dan mengakses data yang tidak boleh diakses menggunakan metode ini dalam JavaScript.

Kedua, haruskah kita menghindari hal-hal yang rumit, yang pasti masalahnya bukan kita memiliki fasilitas ini tetapi masalahnya adalah ada pengembang di luar sana yang mengklaim melakukan JavaScript tetapi tidak tahu cara kerja operator ini ?? Cukup sederhana. nilai ++, beri saya nilai saat ini dan setelah ekspresi tambahkan satu untuk itu, nilai ++, tambahkan nilai sebelum memberi saya itu.

Ekspresi seperti +++ ++ b, mudah dikerjakan jika Anda hanya mengingat yang di atas.

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

Saya kira Anda baru saja ingat siapa yang harus membaca kode, jika Anda memiliki tim yang tahu JS dalam ke luar maka Anda tidak perlu khawatir. Jika tidak maka komentari, tulis berbeda, dll. Lakukan apa yang harus Anda lakukan. Saya tidak berpikir peningkatan dan penurunan pada dasarnya buruk atau menghasilkan bug, atau menciptakan kerentanan, mungkin hanya sedikit terbaca tergantung pada audiens Anda.

Ngomong-ngomong, kupikir Douglas Crockford adalah legenda, tapi kupikir dia menyebabkan banyak ketakutan pada operator yang tidak pantas mendapatkannya.

Saya hidup untuk terbukti salah ...


10

Contoh lain, lebih sederhana daripada yang lainnya dengan pengembalian sederhana dengan nilai tambah:

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

Seperti yang Anda lihat, tidak ada kenaikan / penurunan pasca harus digunakan pada pernyataan kembali, jika Anda ingin operator ini mempengaruhi hasilnya. Tetapi pengembalian tidak "menangkap" operator pasca kenaikan / penurunan:

function closureIncrementTest() {
    var x = 0;

    function postIncrementX() {
        return x++;
    }

    var y = postIncrementX();

    console.log(x); // 1
}

Hanya satu dari fungsi Anda yang menerima x sebagai parameter
Calimero100582

8

Saya pikir programmer harus kompeten dalam bahasa yang mereka gunakan; gunakan dengan jelas; dan gunakan dengan baik. Saya tidak berpikir mereka harus melumpuhkan bahasa yang mereka gunakan secara artifisial. Saya berbicara dari pengalaman. Saya pernah bekerja secara harfiah di sebelah toko Cobol di mana mereka tidak menggunakan ELSE 'karena terlalu rumit'. Reductio ad absurdam.


@ downvoter Menarik. Anda tidak berpikir programmer harus kompeten dalam bahasa ini? Anda pikir mereka harus melumpuhkan bahasa secara artifisial? Yang mana itu? Tidak ada pilihan ketiga di sini.
Marquis of Lorne

1
dan upvote untuk contoh COBOL, membuat saya lebih senang bahwa COBOL sebagian besar mati sebelum saya masuk ke pengkodean
Mark K Cowan

1
@ MarkCowan saya tidak mengerti mengapa. Maksud saya adalah tentang pembatasan sewenang-wenang, bukan bahasa. Anekdot tidak menunjukkan ada yang salah dengan Cobol. Apa yang perlu mati adalah toko pemrograman itu, dan ternyata berhasil. Kunjungi isi perut setiap bank besar dan Anda akan menemukan Cobol hidup dan sehat.
Marquis of Lorne

2

Seperti disebutkan dalam beberapa jawaban yang ada (yang mengganggu saya tidak dapat mengomentari), masalahnya adalah bahwa x ++ ++ x mengevaluasi nilai yang berbeda (sebelum vs setelah kenaikan), yang tidak jelas dan dapat sangat membingungkan - jika nilai itu digunakan. cdmckay menyarankan dengan bijak untuk memungkinkan penggunaan operator kenaikan, tetapi hanya dengan cara yang nilai yang dikembalikan tidak digunakan, misalnya pada barisnya sendiri. Saya juga akan menyertakan penggunaan standar dalam loop for (tetapi hanya dalam pernyataan ketiga, yang nilai kembaliannya tidak digunakan). Saya tidak bisa memikirkan contoh lain. Telah "dibakar" sendiri, saya akan merekomendasikan pedoman yang sama untuk bahasa lain juga.

Saya tidak setuju dengan klaim bahwa ini terlalu ketat karena banyak programmer JS yang tidak berpengalaman. Ini adalah jenis penulisan yang tepat khas dari programmer "terlalu pintar", dan saya yakin itu jauh lebih umum dalam bahasa yang lebih tradisional dan dengan pengembang JS yang memiliki latar belakang dalam bahasa tersebut.


1
Terima kasih balasannya. Anda akan membutuhkan nilai reputasi 50 atau lebih baik untuk memberikan komentar. Lihat: stackoverflow.com/faq
artlung

1
@artlung: Saya sadar akan hal itu, dan tentang alasan di baliknya. Saya hanya mengatakan itu menjengkelkan :)
Dekat Privman

2

Dalam pengalaman saya, ++ i atau i ++ tidak pernah menyebabkan kebingungan selain ketika pertama kali belajar tentang cara kerja operator. Sangat penting untuk loop paling dasar dan loop sementara yang diajarkan oleh kursus sekolah menengah atau perguruan tinggi yang diajarkan dalam bahasa di mana Anda dapat menggunakan operator. Saya pribadi menemukan melakukan sesuatu seperti apa di bawah ini untuk melihat dan membaca lebih baik daripada sesuatu dengan ++ berada di baris terpisah.

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

Pada akhirnya ini adalah preferensi gaya dan bukan apa-apa lagi, yang lebih penting adalah bahwa ketika Anda melakukan ini dalam kode Anda, Anda tetap konsisten sehingga orang lain yang bekerja pada kode yang sama dapat mengikuti dan tidak harus memproses fungsi yang sama dengan cara yang berbeda. .

Juga, Crockford tampaknya menggunakan i- = 1, yang menurut saya lebih sulit dibaca daripada --i atau i--


2

2 sen saya adalah bahwa mereka harus dihindari dalam dua kasus:

1) Ketika Anda memiliki variabel yang digunakan di banyak baris dan Anda menambah / menguranginya pada pernyataan pertama yang menggunakannya (atau terakhir, atau, lebih buruk lagi, di tengah):

// 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 ) ...

Dalam contoh-contoh seperti ini, Anda dapat dengan mudah kehilangan bahwa variabel bertambah / dikurangi secara otomatis atau bahkan menghapus pernyataan pertama. Dengan kata lain, gunakan hanya di blok yang sangat pendek atau di mana variabel muncul di blok hanya pada beberapa pernyataan dekat.

2) Dalam kasus multiple ++ dan - tentang variabel yang sama dalam pernyataan yang sama. Sangat sulit untuk mengingat apa yang terjadi dalam kasus-kasus seperti ini:

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

Ujian dan tes profesional bertanya tentang contoh-contoh seperti di atas dan memang saya telah menemukan pertanyaan ini sambil mencari dokumentasi tentang salah satunya, tetapi dalam kehidupan nyata orang tidak boleh dipaksa untuk berpikir banyak tentang satu baris kode.


1

Apakah Fortran bahasa seperti-C? Ini tidak memiliki ++ atau -. Inilah cara Anda menulis loop :

     integer i, n, sum

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

Elemen indeks i bertambah oleh aturan bahasa setiap kali melalui loop. Jika Anda ingin bertambah dengan sesuatu selain 1, hitung mundur dua misalnya, sintaksnya adalah ...

      integer i

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

Apakah seperti Python C? Ini menggunakan rentang dan daftar pemahaman dan sintaksis lain untuk memotong kebutuhan untuk meningkatkan indeks:

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

Jadi berdasarkan eksplorasi dasar dari dua alternatif ini, perancang bahasa dapat menghindari ++ dan - dengan mengantisipasi kasus penggunaan dan memberikan sintaksis alternatif.

Apakah Fortran dan Python memiliki magnet bug lebih sedikit daripada bahasa prosedural yang memiliki ++ dan -? Saya tidak punya bukti.

Saya mengklaim bahwa Fortran dan Python adalah seperti-C karena saya belum pernah bertemu seseorang yang fasih dalam C yang tidak bisa dengan akurasi 90% menebak dengan benar maksud dari Fortran atau Python yang tidak dikaburkan.


1
Ya, IFortran dari tahun 1950-an, sedangkan C dari tahun 1970-an, jadi mungkin tidak untuk Fortran seperti-C. Contoh Python kekurangan sesuatu seperti operator plusplus menarik. Iterasi atas struktur data lebih mudah ditangani dengan Python, Python adalah JavaScript berorientasi objek yang "berbeda". Mungkin saran Crockford adalah tentang menggunakan lebih banyak sintaks mirip OO untuk iterasi.
artlung
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.