ทำไมลูก (วัตถุ) ของฉันจึงไม่หดตัวหรือหายไป?


208

http://jsfiddle.net/goldrunt/jGL84/42/ นี่มาจากบรรทัดที่ 84 ในซอ JS นี้ มีเอฟเฟ็กต์ต่าง ๆ 3 แบบที่สามารถนำไปใช้กับลูกบอลได้โดยใช้บรรทัดที่ไม่ใส่เครื่องหมาย 141-146 เอฟเฟกต์ 'ตีกลับ' ทำงานได้ตามปกติ แต่เอฟเฟกต์ 'asplode' นั้นไม่ได้ทำอะไรเลย ฉันควรรวมฟังก์ชั่น 'ลดขนาด' ในฟังก์ชั่น asplode หรือไม่?

// balls shrink and disappear if they touch
var shrink = function(p) {
    for (var i = 0; i < 100; i++) {
        p.radius -= 1;
    }
    function asplode(p) {
        setInterval(shrink(p),100);
        balls.splice(p, 1);
    }
}

12
asplodeไม่ได้ประกาศในขอบเขตส่วนกลาง (หรือโดยเฉพาะอย่างยิ่งไม่ได้กำหนดไว้ในขอบเขตที่เข้าถึงได้update) ตรวจสอบคอนโซลของเรา
apsillers

39
โชคดีที่มีballs.splice() p
m59

1
Uncaught ReferenceError: asplode is not definedคุณมีข้อผิดพลาด ฟังก์ชั่นasplode()ไม่สามารถมองเห็นได้
Anto Jurković

2
asplodeไม่ได้อยู่ในขอบเขตที่ถูกต้องsetIntervalควรได้รับการอ้างอิงฟังก์ชั่นspliceต้องการดัชนี - หรือบางทีโลกกำลังหดตัวลงกับคุณjsfiddle.net/5f85b
bendytree

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

คำตอบ:


65

รหัสของคุณมีปัญหาเล็กน้อย

ก่อนอื่นในคำนิยามของคุณ:

var shrink = function(p) {
    for (var i = 0; i < 100; i++) {
        p.radius -= 1;
    }

    function asplode(p) {
         setInterval(shrink(p),100);
        balls.splice(p, 1);
    }
}

asplodeอยู่ภายในขอบเขตภายในshrinkจึงไม่สามารถเข้าถึงรหัสupdateที่คุณพยายามโทรหา ขอบเขต JavaScript เป็นฟังก์ชั่นที่ใช้จึงupdateไม่สามารถมองเห็นเพราะมันไม่ได้อยู่ภายในasplode shrink( ในคอนโซลของคุณคุณจะเห็นข้อผิดพลาดดังนี้: Uncaught ReferenceError: asplode is not defined.)

คุณอาจลองแทนที่asplodeภายนอกshrink:

var shrink = function(p) {
    for (var i = 0; i < 100; i++) {
        p.radius -= 1;
    }
}

function asplode(p) {
     setInterval(shrink(p),100);
     balls.splice(p, 1);
}

อย่างไรก็ตามรหัสของคุณมีปัญหาอื่น ๆ อีกมากมายที่อยู่นอกขอบเขตของคำถามนี้:

  • setIntervalคาดหวังฟังก์ชั่น setInterval(shrink(p), 100)สาเหตุที่setIntervalจะได้รับค่าตอบแทนจากการเรียก shrink(p)ทันที คุณอาจต้องการ

    setInterval(function() { shrink(p) }, 100)
  • รหัสของคุณfor (var i = 0; i < 100; i++) { p.radius -= 1; }อาจไม่ทำในสิ่งที่คุณคิด สิ่งนี้จะเรียกใช้การดำเนินการลดลงทันที 100 ครั้งจากนั้นจึงแสดงผลลัพธ์ให้เห็น หากคุณต้องการเรนเดอร์ลูกบอลใหม่ในขนาดใหม่แต่ละขนาดคุณจะต้องดำเนินการลดทอนแต่ละครั้งภายในการโทรกลับเวลาแยกต่างหาก (เช่นการsetIntervalดำเนินการ)

  • .spliceคาดว่าจะเป็นดัชนีตัวเลขไม่ใช่วัตถุ คุณสามารถรับดัชนีตัวเลขของวัตถุด้วยindexOf:

    balls.splice(balls.indexOf(p), 1);
  • เมื่อถึงช่วงเวลาที่คุณรันเป็นครั้งแรกballs.spliceข้อความสั่งนั้นได้เกิดขึ้นแล้ว (มันเกิดขึ้นประมาณ 100ms ที่แล้วเพื่อให้แน่นอน) ฉันคิดว่านั่นไม่ใช่สิ่งที่คุณต้องการ แต่คุณควรจะมีฟังก์ชั่น decrementing ที่ได้รับการเรียกซ้ำโดยsetIntervalและในที่สุดก็จะดำเนินการหลังจากที่balls.splice(p,1)p.radius == 0


21
setInterval(shrink(p),100);

สิ่งนี้ไม่ได้ทำในสิ่งที่คุณคิด สายนี้shrinkผ่านมันแล้วผ่านผลให้ p ส่งกลับดังนั้นบรรทัดนี้ไม่ได้ใส่อะไรเลยในช่วงเวลาหนึ่งsetIntervalshrink(p)undefined

คุณอาจต้องการ:

setInterval(function(){
    shrink(p)
}, 100);

1
@ tereško: ฉันจะอยู่กับว่า :)
จรวดวัตถุอันตราย
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.