กำหนดตัวแปรหลายตัวให้เป็นค่าเดียวกันใน Javascript


177

ฉันได้เริ่มต้นตัวแปรหลายตัวในขอบเขตทั่วโลกในไฟล์ JavaScript:

var moveUp, moveDown, moveLeft, moveRight;
var mouseDown, touchDown;

ฉันต้องการตั้งค่าตัวแปรทั้งหมดเหล่านี้เป็นเท็จนี่คือรหัสที่ฉันมีในขณะนี้:

moveUp    = false;
moveDown  = false;
moveLeft  = false;
moveRight = false
mouseDown = false;
touchDown = false;

มีวิธีใดบ้างที่ฉันสามารถตั้งค่าตัวแปรทั้งหมดเหล่านี้ให้เป็นค่าเดียวกันในหนึ่งบรรทัดของรหัสหรือเป็นรหัสที่ฉันมีอยู่ในขณะนี้มีวิธีที่ดีที่สุดในการทำสิ่งนี้


8
ผู้อ่านทั้งหมด: โปรดดูคำตอบที่สองด้านล่างก่อนที่คุณจะตัดสินใจใช้คำตอบยอดนิยมในรหัสของคุณ ความสงบ.
Govind Rai

อย่าพยายามทำเช่นนี้เพราะในหน่วยความจำจะมีเพียงหนึ่งตัวแปรและอื่น ๆ จะเป็นสำเนาหรือการอ้างอิงสำหรับหนึ่งนั้นถ้าคุณเปลี่ยนค่าจากหนึ่งทั้งหมดจะได้รับผลกระทบ
Lucas Matos

@LucasMatos ไม่ได้สำหรับดั้งเดิม
Dave Newton

คำตอบ:


290

ไม่มีอะไรหยุดคุณจากการทำ

moveUp = moveDown = moveLeft = moveRight = mouseDown = touchDown = false;

ตรวจสอบตัวอย่างนี้

var a, b, c;
a = b = c = 10;
console.log(a + b + c)


13
คุณอาจต้องการแสดงความคิดเห็นว่าพฤติกรรมจะแตกต่างจากชนิดดั้งเดิมและประเภทการอ้างอิงอย่างไรเมื่อกำหนดค่าตามที่คุณแนะนำ
Steven Wexler

26
ใช่ถ้าทำสิ่งนี้กับวัตถุตัวแปรทั้งหมดจะเป็นนามแฝงของวัตถุ IE function MyObj(){this.x=1} var a,b; a = b = new MyObj(); ++a.xก็จะเพิ่มb.xคุณสมบัติ
AlexMorley-Finch

27
ปัญหาการกำหนดขอบเขต! stackoverflow.com/questions/1758576/…
doublejosh

4
ฉันจะบอกว่าอย่าใช้วิธีการนี้หากคุณไม่ได้กำหนดตัวแปรทั้งหมดไว้ทางด้านซ้ายของการมอบหมาย
พลเมือง conn

2
ดังที่ @doublejosh กล่าวว่ามีปัญหาในการกำหนดขอบเขตที่คุณไม่ได้กล่าวถึง
58

90

ไม่มีอะไรหยุดคุณจากการทำข้างต้น แต่ถือขึ้น!

มี gotchas บ้าง การกำหนดใน Javascript มาจากขวาไปซ้ายดังนั้นเมื่อคุณเขียน:

var moveUp = moveDown = moveLeft = moveRight = mouseDown = touchDown = false;

มันแปลเป็น:

var moveUp = (moveDown = (moveLeft = (moveRight = (mouseDown = (touchDown = false)))));

ซึ่งแปลเป็น:

var moveUp = (window.moveDown = (window.moveLeft = (window.moveRight = (window.mouseDown = (window.touchDown = false)))));

คุณเพิ่งสร้างตัวแปรทั่วโลก 5 ตัวโดยที่ไม่แน่ใจว่าคุณไม่ต้องการทำอะไร

หมายเหตุ: windowตัวอย่างข้างต้นของฉันจะถือว่าคุณกำลังเรียกใช้รหัสของคุณในเบราว์เซอร์จึง หากคุณอยู่ในสภาพแวดล้อมที่แตกต่างกันตัวแปรเหล่านี้จะเชื่อมต่อกับสิ่งที่บริบทโลกเกิดขึ้นสำหรับสภาพแวดล้อมนั้น (เช่นใน Node.js มันจะแนบไปglobalซึ่งเป็นบริบทระดับโลกสำหรับสภาพแวดล้อมนั้น)

ตอนนี้คุณสามารถประกาศตัวแปรทั้งหมดของคุณก่อนจากนั้นกำหนดให้เป็นค่าเดียวกันและคุณสามารถหลีกเลี่ยงปัญหาได้

var moveUp, moveDown, moveLeft, moveRight, mouseDown, touchDown;
moveUp = moveDown = moveLeft = moveRight = mouseDown = touchDown = false;

เรื่องสั้นสั้น ๆ ทั้งสองวิธีใช้งานได้ดี แต่วิธีแรกอาจแนะนำบั๊กอันตรายในรหัสของคุณ อย่ากระทำบาปในการทิ้งเนมสเปซส่วนกลางด้วยตัวแปรท้องถิ่นหากไม่จำเป็นจริงๆ


Sidenote: ตามที่ระบุไว้ในความคิดเห็น (และนี่ไม่ใช่เพียงในกรณีของคำถามนี้) หากค่าที่คัดลอกในคำถามนั้นไม่ใช่ค่าดั้งเดิม แต่เป็นวัตถุแทนคุณควรทราบเกี่ยวกับการคัดลอกด้วยมูลค่าเทียบกับการคัดลอกโดยอ้างอิง เมื่อใดก็ตามที่กำหนดวัตถุการอ้างอิงไปยังวัตถุจะถูกคัดลอกแทนวัตถุจริง ตัวแปรทั้งหมดจะยังคงชี้ไปที่วัตถุเดียวกันดังนั้นการเปลี่ยนแปลงใด ๆ ในตัวแปรหนึ่งจะสะท้อนให้เห็นในตัวแปรอื่น ๆ และจะทำให้คุณปวดหัวที่สำคัญถ้าคุณตั้งใจที่จะคัดลอกค่าวัตถุและไม่ใช่การอ้างอิง


2
ถ้าเราทำอย่างเดียวกันกับปล่อย
P-RAD

นอกเหนือจากการmoveUpกลายเป็นบล็อกขอบมันจะไม่สร้างความแตกต่าง 5 ตัวแปรทั่วโลกจะยังคงถูกประกาศ
Govind Rai

1
@GovindRai มากแตกต่างจากvar a, b, c; a = b = c = 10; var a = b = c = 10;ดังนั้นคำตอบที่ยอมรับนั้นถูกต้อง คุณกำลังจัดการปัญหาที่ไม่เกี่ยวข้องกับคำตอบที่ยอมรับ
Elis Byberi

1
@ElisByberi ขอบคุณสำหรับความคิดเห็นของคุณ คุณไม่ผิด เป้าหมายของคำตอบของฉันคือพูดประโยคแรกในคำตอบที่ยอมรับได้ ฉันได้ให้คำตอบที่ชัดเจนยิ่งขึ้นเกี่ยวกับเรื่องนั้น
Govind Rai

1
@ P-RAD เฉพาะตัวแปรแรกที่ประกาศโดยใช้การอนุญาตเท่านั้นที่จะมีอยู่ในขอบเขตการปิดล้อม
Uday Hiwarale

9

มีตัวเลือกอื่นที่ไม่ได้รับ gotchas ทั่วโลกเมื่อพยายามเริ่มต้นตัวแปรหลายตัวเป็นค่าเดียวกัน ไม่ว่าจะเป็นทางยาวหรือไม่ก็เป็นการดีกว่า มันอาจจะช้ากว่าและอาจจะใช่หรือไม่ก็ได้ ในกรณีเฉพาะของคุณฉันคิดว่าทางยาวน่าจะอ่านง่ายและบำรุงรักษาได้ดีกว่าและเร็วกว่า

อื่น ๆวิธีใช้การกำหนด Destructuring

let [moveUp, moveDown,
     moveLeft, moveRight,
     mouseDown, touchDown] = Array(6).fill(false);

console.log(JSON.stringify({
    moveUp, moveDown,
    moveLeft, moveRight,
    mouseDown, touchDown
}, null, '  '));

// NOTE: If you want to do this with objects, you would be safer doing this
let [obj1, obj2, obj3] = Array(3).fill(null).map(() => ({}));
console.log(JSON.stringify({
    obj1, obj2, obj3
}, null, '  '));
// So that each array element is a unique object

// Or another cool trick would be to use an infinite generator
let [a, b, c, d] = (function*() { while (true) yield {x: 0, y: 0} })();
console.log(JSON.stringify({
    a, b, c, d
}, null, '  '));

// Or generic fixed generator function
function* nTimes(n, f) {
    for(let i = 0; i < n; i++) {
        yield f();
    }
}
let [p1, p2, p3] = [...nTimes(3, () => ({ x: 0, y: 0 }))];
console.log(JSON.stringify({
    p1, p2, p3
}, null, '  '));

นี้ช่วยให้คุณเริ่มต้นชุดของvar, letหรือconstตัวแปรค่าเดียวกันในบรรทัดเดียวทั้งหมดที่มีขอบเขตเดียวกันคาดว่า

อ้างอิง:


1
อย่างไรก็ตามระวัง หากการกำหนดวัตถุฟังก์ชันหรืออาร์เรย์ให้กับตัวแปรหลายตัวโดยใช้วิธีนี้แต่ละตัวแปรจะเป็นนามแฝงของsameวัตถุ การปรับเปลี่ยนหนึ่งอย่างจะส่งผลกระทบต่อคนอื่น ๆ ...
Doug Coburn

-6

ใส่ varible ในอาร์เรย์และใช้สำหรับ Loop เพื่อกำหนดค่าเดียวกันให้กับตัวแปรหลายตัว

  myArray[moveUP, moveDown, moveLeft];

    for(var i = 0; i < myArray.length; i++){

        myArray[i] = true;

    }

3
นี่เป็นสิ่งที่ผิดมากคำสั่งแรกไม่ได้ทำให้เกิดความรู้สึกเชิงประโยคและ for for loop เป็นเพียงการกำหนดค่าให้กับดัชนี myArray
undefinederror
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.