Beberapa tugas kiri dengan JavaScript

186
var var1 = 1,
    var2 = 1,
    var3 = 1;

Ini sama dengan ini:

var var1 = var2 = var3 = 1;

Saya cukup yakin ini adalah urutan variabel didefinisikan: var3, var2, var1, yang akan setara dengan ini:

var var3 = 1, var2 = var3, var1 = var2;

Apakah ada cara untuk mengonfirmasi ini dalam JavaScript? Mungkin menggunakan beberapa profiler?

David Calhoun
sumber
6
PENUGASAN TERJADI KIRI operator javascript diutamakan
neaumusic
apakah ini juga berlaku jika saya menggunakan this.var1 = this.var2 = this.var3 = 1?
Gangadhar JANNU

Jawaban:

404

Sebenarnya,

var var1 = 1, var2 = 1, var3 = 1;

adalah tidak setara dengan:

var var1 = var2 = var3 = 1;

Perbedaannya adalah dalam pelingkupan:

function good() {
  var var1 = 1, var2 = 1, var3 = 1;
}

function bad() {
  var var1 = var2 = var3 = 1;
}

good();
console.log(window.var2); // undefined

bad();
console.log(window.var2); // 1. Aggh!

Sebenarnya ini menunjukkan bahwa penugasan itu asosiatif yang benar. The badcontoh adalah setara dengan:

var var1 = (window.var2 = (window.var3 = 1));
Crescent Fresh
sumber
44
Sial, itu tidak terduga. Terima kasih atas tipnya, saya akan berhati-hati untuk itu.
David Calhoun
10
@ SkinnyG33k karena kanan ke kiri. sehingga akan mem-parsing paling kanan sebelum paling kiri. begitu var var1=var2terjadi setelah var3 = 1dan sesudah var2 = var3. itu sepertivar3=1; var2=var3; var var1=var2
gcb
12
Sebagai catatan: jika Anda tahu Anda ingin melakukan hal seperti ini sebelumnya, Anda masih dapat memecah definisi dari tugas. Jadi: var v1, v2, v3;Kemudian nanti: v1 = v2 = v3 = 6;Mereka masih akan berada dalam lingkup lokal. Karena David menyebutkan peringatan, ini akan berfungsi seperti yang diharapkan (jika sebelum var'd):alert(v1 = v2 = v3 = 6);
ShawnFumo
3
Persis. Tetapi jika kita mengikuti beberapa praktik terbaik umum, dalam hal ini dengan mendeklarasikan variabel kita di atas kita dapat menjaga dari kesalahan yang tidak diinginkan dan menghindari variabel lokal yang bocor ke lingkup global. Lihat: jsfiddle.net/gleezer/r9Mu8/1
Nobita
1
"Dang, itu tidak terduga." Mengapa ini tidak terduga? Sebagian besar bahasa mengharuskan Anda mendeklarasikan variabel Anda sebelum digunakan. JavaScript tidak berbeda, jika Anda lalai untuk mendeklarasikan variabel Anda, maka defaultnya adalah objek jendela global. Mulai gunakan 'gunakan ketat' dalam javascript Anda dan Anda akan menjadi programmer JavaScript yang lebih baik.
cchamberlain
20

Penugasan dalam javascript berfungsi dari kanan ke kiri. var var1 = var2 = var3 = 1;.

Jika nilai dari salah satu variabel ini adalah 1setelah pernyataan ini, maka secara logis itu harus dimulai dari kanan, jika tidak nilai atau var1dan var2tidak akan ditentukan.

Anda dapat menganggapnya setara dengan di var var1 = (var2 = (var3 = 1));mana set kurung paling dalam dievaluasi terlebih dahulu.

Justin Johnson
sumber
1
Terima kasih, ini pasti membantu. Ini membantu untuk berpikir dalam hal kesalahan apa yang akan dilemparkan jika dievaluasi selain dari kanan ke kiri (dalam hal ini, kesalahannya adalah bahwa var1 / var2 tidak terdefinisi).
David Calhoun
5
Ini sebenarnya kesalahan sintaksis. Anda tidak dapat (segera memilikinya var. Menghapus set kurung luar memungkinkan untuk mengkompilasi tanpa kesalahan var var1 = (var2 = (var3 = 1));,. Pada saat itu saya merasa bahwa itu tidak menggambarkan hal itu dengan baik, tetapi saya kira itu sama.
Justin Johnson
var var1 = var2 = var3 = 1;. sama dengan var var3 = 1; var var2 = var3; var var1 = var2;
xgqfrms
8

var var1 = 1, var2 = 1, var3 = 1;

Dalam hal ini varkata kunci berlaku untuk ketiga variabel.

var var1 = 1,
    var2 = 1,
    var3 = 1;

yang tidak setara dengan ini:

var var1 = var2 = var3 = 1;

Dalam hal ini varkata kunci di balik layar hanya berlaku var1karena pengangkatan variabel dan sisa ekspresi dievaluasi secara normal sehingga variabel var2, var3menjadi global

Javascript memperlakukan kode ini dalam urutan ini:

/*
var 1 is local to the particular scope because of var keyword
var2 and var3 will become globals because they've used without var keyword
*/

var var1;   //only variable declarations will be hoisted.

var1= var2= var3 = 1; 
Gangadhar JANNU
sumber
8
a = (b = 'string is truthy'); // b gets string; a gets b, which is a primitive (copy)
a = (b = { c: 'yes' }); // they point to the same object; a === b (not a copy)

(a && b)secara logis (a ? b : a)dan berperilaku seperti multiplikasi (mis. !!a * !!b)

(a || b)secara logis (a ? a : b)dan berperilaku seperti penambahan (mis. !!a + !!b)

(a = 0, b)kependekan dari tidak peduli jika aitu benar, secara implisit kembalib


a = (b = 0) && "nope, but a is 0 and b is 0"; // b is falsey + order of operations
a = (b = "b is this string") && "a gets this string"; // b is truthy + order of ops

Precedence Operator JavaScript (Urutan Operasi)

Perhatikan bahwa operator koma sebenarnya adalah operator yang paling tidak diistimewakan, tetapi tanda kurung adalah yang paling istimewa, dan mereka berjalan seiring ketika membangun ekspresi satu baris.


Pada akhirnya, Anda mungkin memerlukan 'thunks' daripada nilai-nilai yang dikodekan dengan keras, dan bagi saya, thunk adalah fungsi dan nilai yang dihasilkan ('hal' yang sama).

const windowInnerHeight = () => 0.8 * window.innerHeight; // a thunk

windowInnerHeight(); // a thunk
neaumusik
sumber
4

Coba ini:

var var1=42;
var var2;

alert(var2 = var1); //show result of assignment expression is assigned value
alert(var2); // show assignment did occur.

Catat single '=' pada peringatan pertama. Ini akan menunjukkan bahwa hasil dari ekspresi penugasan adalah nilai yang diberikan, dan peringatan 2 akan menunjukkan kepada Anda bahwa penugasan memang terjadi.

Secara logis, tugas itu harus dirantai dari kanan ke kiri. Namun, karena ini semua atom ke javascript (tidak ada threading) mesin tertentu dapat memilih untuk benar-benar mengoptimalkannya sedikit berbeda.

Joel Coehoorn
sumber
1
Terima kasih atas jawabannya. Saya pikir saya sedang mencari cara untuk menggunakan peringatan sambil tetap mempertahankan struktur multi-tugas (a = b = c), tapi saya tidak berpikir itu mungkin.
David Calhoun
1
Pernyataan individu seperti itu dalam javascript (dan, meskipun beberapa ekspresi, yang semuanya berfungsi untuk satu pernyataan) dapat dianggap atom. Anda harus memecahnya.
Joel Coehoorn
1

Sudah jelas sekarang, bahwa mereka tidak sama. Cara untuk kode itu

var var1, var2, var3
var1 = var2 = var3 = 1

Dan, bagaimana dengan biayanya? Persis sama dengan var, jangan biarkan assigment let membingungkan Anda karena ruang lingkup blok.

let var1 = var2 = 1 // here var2 belong to the global scope

Kita bisa melakukan hal berikut:

let v1, v2, v3
v1 = v2 = v3 = 2

Catatan: btw, saya tidak merekomendasikan menggunakan banyak tugas, bahkan beberapa deklarasi di baris yang sama.

fenderOne
sumber
-3

coffee-script dapat mencapai ini dengan penuh percaya diri ..

for x in [ 'a', 'b', 'c' ] then "#{x}" : true

[ { a: true }, { b: true }, { c: true } ]

Alex Gray
sumber
7
Ini tidak benar-benar menjawab pertanyaan itu. Harap baca kembali pertanyaannya.
Martin
30
siapa yang peduli tentang naskah kopi
neaumusic