JavaScript ile birden fazla soldan atama


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

Bu şuna eşdeğerdir:

var var1 = var2 = var3 = 1;

Bu değişkenlerin tanımlandığı sıra oldukça eminim: var3, var2, var1, buna eşdeğer olacaktır:

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

Bunu JavaScript'te onaylamanın herhangi bir yolu var mı? Muhtemelen biraz profiler mi kullanıyorsunuz?


6
ÖDEV soldan sağa OLUR javascript operatör öncelik
neaumusic

kullanırsam bu da uygulanabilir this.var1 = this.var2 = this.var3 = 1mi?
Gangadhar JANNU

Yanıtlar:


404

Aslında,

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

olduğu değil eşdeğerdir:

var var1 = var2 = var3 = 1;

Fark kapsamda:

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!

Aslında bu, görevin doğru ilişkilendirici olduğunu gösterir. badÖrnek eşdeğerdir:

var var1 = (window.var2 = (window.var3 = 1));

44
Dang, bu beklenmedik bir şey. Bahşiş için teşekkürler, buna dikkat edeceğim.
David Calhoun

10
@ SkinnyG33k çünkü sağdan sola. böylece en sağdan en soldan ayrışacaktır. böylece var var1=var2sonra var3 = 1ve sonra olur var2 = var3. gibivar3=1; var2=var3; var var1=var2
gcb

12
Sadece not etmek için: Bu tür bir şeyi önceden yapmak istediğinizi biliyorsanız, tanımı ödevden ayırabilirsiniz. Öyleyse: var v1, v2, v3;O zaman sonra: v1 = v2 = v3 = 6;Hala yerel kapsamda olacaklar. David uyarılardan bahsettiğinden, bu beklendiği gibi çalışacaktır (eğer önceden var ise):alert(v1 = v2 = v3 = 6);
ShawnFumo

3
Kesinlikle. Ancak bazı ortak en iyi uygulamaları takip edersek, bu durumda değişkenlerimizi en üstte beyan ederek, istenmeyen hatalardan uzak durabilir ve yerel değişkenlerin küresel kapsama sızmasını önleyebiliriz. Bkz: jsfiddle.net/gleezer/r9Mu8/1
Nobita

1
"Dang, bu beklenmedik bir şey." Bu neden beklenmiyor? Çoğu dil, kullanmadan önce değişkenlerinizi bildirmenizi gerektirir. JavaScript farklı değildir, değişkeninizi bildirmeyi ihmal ederseniz, varsayılan olarak global pencere nesnesidir. Javascriptinizde 'katı kullanın' kullanmaya başlayın ve daha iyi bir JavaScript programcısı olacaksınız.
cchamberlain

20

Javascript'te atama sağdan sola doğru çalışır. var var1 = var2 = var3 = 1;.

Bu değişkenlerin herhangi birinin değeri ise 1bu ifadeye sonra, daha sonra mantıksal o sağdan aksi değer veya başlamış olmalı var1ve var2tanımsız olacaktır.

var var1 = (var2 = (var3 = 1));İlk önce en iç parantez kümesinin değerlendirildiği yerle eşdeğer olduğunu düşünebilirsiniz .


1
Teşekkürler, bu kesinlikle yardımcı olur. Sağdan sola dışında değerlendirilirse hangi hataların atılacağını düşünmeye yardımcı olur (bu durumda hata var1 / var2 tanımsızdır).
David Calhoun

5
Aslında bir sözdizimi hatası. (Hemen sonra sahip olamazsınız var. Dış parantez setinin kaldırılması hatasız derlenmesini sağlar var var1 = (var2 = (var3 = 1));. O zaman noktayı da iyi göstermediğini hissettim, ama sanırım aynı.
Justin Johnson

var var1 = var2 = var3 = 1;. eşittir var var3 = 1; var var2 = var3; var var1 = var2;
xgqfrms

8

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

Bu durumda, varanahtar kelime üç değişkenin tümüne uygulanabilir.

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

buna eşdeğer değildir:

var var1 = var2 = var3 = 1;

Bu durumda ekranların arkasındaki varanahtar kelime yalnızca var1değişken kaldırma nedeniyle uygulanabilir ve ifadenin geri kalanı normal olarak değerlendirilir, böylece değişkenler globalvar2, var3 hale gelir

Javascript bu kodu şu sırayla ele alır:

/*
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; 

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)mantıklıdır (a ? b : a)ve çarpma gibi davranır (ör. !!a * !!b)

(a || b)mantıklıdır (a ? a : b)ve toplama gibi davranır (ör. !!a + !!b)

(a = 0, b)adoğruysa umursamaz olmamak, dolaylı olarak geri dönmekb


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

JavaScript Operatör Önceliği (İşlem Sırası)

Virgül işlecinin aslında en az ayrıcalıklı işleç olduğunu, ancak parantezin en ayrıcalıklı olduğunu ve tek satırlık ifadeler oluştururken el ele gittiğini unutmayın.


Sonunda, sabit kodlanmış değerlerden ziyade 'thunk'lara ihtiyacınız olabilir ve bana göre bir thunk hem fonksiyon hem de sonuç değeridir (aynı' şey ').

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

windowInnerHeight(); // a thunk

4

Bunu dene:

var var1=42;
var var2;

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

İlk uyarıdaki tek '=' işaretini not edin. Bu, atama ifadesinin sonucunun atanan değer olduğunu ve 2. uyarıda atamanın gerçekleştiğini gösterir.

Mantıksal olarak, atamanın sağdan sola zincirlenmiş olması gerekir. Bununla birlikte, bunların hepsi javascript için atomik olduğu için (diş çekme yoktur) belirli bir motor onu biraz farklı bir şekilde optimize etmeyi seçebilir.


1
Cevap için teşekkürler. Ben hala çok atama yapısı (a = b = c) korurken uyarıları kullanmak için bir yol arıyordum, ama bunun mümkün olduğunu düşünmüyorum.
David Calhoun

1
Javascript'te bunun gibi bireysel ifadeler (ve birkaç ifade olsa da, hepsinin tek bir ifadede işe yaradığı) atomik olarak kabul edilebilir. Onu parçalamak zorunda kalacaksın.
Joel Coehoorn

1

Şimdiye kadar aynı olmadıkları açıktır. Kodlamanın yolu

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

Öyleyse izin vermeye ne dersin? Var ile tam olarak aynı, blok kapsamı nedeniyle tahsisin sizi karıştırmasına izin vermeyin.

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

Aşağıdakileri yapabiliriz:

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

Not: btw, aynı satırda birden fazla bildirim bile değil, birden fazla atama kullanmanızı önermiyorum.


-3

coffee-script bunu aplomb ile başarabilir ..

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

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


7
Bu soruya gerçekten cevap vermiyor. Lütfen soruyu tekrar okuyun.
Martin

30
kim hakkında kahve umurunda
neaumusic
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.