ความยาวตัวอักษรของวัตถุ JavaScript === ไม่ได้กำหนด?

ฉันกำลังพัฒนาฟังก์ชันแอนิเมชันนี้ แต่ฉันมีปัญหา ดูเหมือนว่าฉันไม่สามารถทำสิ่งที่ควรจะเป็นงานง่ายได้ ฉันไม่สามารถรับความยาวของวัตถุได้ หากคุณตรวจสอบ jsFiddle นั้น คุณจะเห็นว่าฉันกำลังใช้งาน alert(properties.length); และมันกำลังส่งคืน undefined ใครเห็นบ้างว่าทำไมถึงเป็นเช่นนั้น?


person Olical    schedule 14.01.2011    source แหล่งที่มา
comment
ความเป็นไปได้ที่ซ้ำกันของ ความยาวของ Javascript Associative Array   -  person ripper234    schedule 31.01.2012


คำตอบ (5)


ออบเจ็กต์ JavaScript ไม่ มีคุณสมบัติ length เพียงแต่มี Arrays เท่านั้น หากคุณต้องการทราบจำนวนคุณสมบัติที่กำหนดไว้บนออบเจ็กต์ คุณต้องวนซ้ำและนับคุณสมบัติเหล่านั้น

นอกจากนี้ for in loop ของคุณมีแนวโน้มที่จะเกิดข้อผิดพลาดเนื่องจากส่วนขยาย Object.prototype เนื่องจาก in จะเคลื่อนที่ผ่าน สายโซ่ต้นแบบ ที่สมบูรณ์ และระบุคุณสมบัติ ทั้งหมด ที่อยู่บนสายโซ่

ตัวอย่าง

// Poisoning Object.prototype
Object.prototype.bar = 1;

var foo = {moo: 2};
for(var i in foo) {
    console.log(i); // logs both 'moo' AND 'bar'
}

คุณต้องใช้เมธอด hasOwnProperty บนออบเจ็กต์เพื่อที่จะ กรองคุณสมบัติที่ไม่ต้องการเหล่านั้นออกไป

// still the foo from above
for(var i in foo) {
    if (foo.hasOwnProperty(i)) {
        console.log(i); // only logs 'moo'
    }
}

เฟรมเวิร์ก JavaScript จำนวนมากขยายต้นแบบ การไม่ใช้ hasOwnProperty มักจะนำไปสู่ข้อบกพร่องที่น่ากลัว

อัปเดต

เกี่ยวกับปัญหาจริงที่โค้ดของคุณไม่มีแอนิเมชั่นทั้งสองคุณสมบัติ

for(var p in properties) {
    ...
    for(var i = 0; i <= frames; i++)
    {
        setTimeout((function(exti, element) {
            return function() {

                // p gets overriden by for outer for in loop
                element.style[p] = original + (pixels * exti) + 'px';
            }

        // you need to pass in a copy of the value of p here
        // just like you do with i and element
        })(i, element), i * (1000 / 60), element);
    }
    ....
 }
person Ivo Wetzel    schedule 14.01.2011
comment
ในการนับไลบรารี่จำนวนมาก (เช่น jQuery) จะแตกสลายอย่างน่ากลัวหากคุณขยาย object.prototype ดังนั้นหากคุณใช้หนึ่งในนั้น hasOwnProperty ก็เป็นเพียงการสิ้นเปลืองวงจร cpu - person Martin Jespersen; 14.01.2011
comment
@Martin Jespersen ดังนั้นคุณขายรหัสที่มีคำเตือนใช้เฉพาะกับกรอบ A, B และ C ที่พิมพ์อยู่เท่านั้นหรือไม่ ขออภัย การใช้ hasOwnProperty เป็น* เป็นแนวทางปฏิบัติที่ดี - person Ivo Wetzel; 14.01.2011
comment
ไม่ ฉันแค่เบื่อเว็บที่เต็มไปด้วยโค้ดจาวาสคริปต์ที่ยังห่างไกลจากการปรับปรุงให้เหมาะสมถึงขนาดที่แม้แต่โครมติดขัดอยู่ อีกอย่าง ฉันเดาว่าฉันควรจะขอบคุณเพราะฉันหาเงินได้เพื่อล้างความยุ่งเหยิงที่คนอื่นทำ :P - person Martin Jespersen; 14.01.2011
comment
ฉันไม่เข้าใจว่าคุณกำลังทำอะไรกับสิ่ง hasOwnProperty ทั้งหมด ฉันไม่รู้ว่าฉันกำลังตั้งค่าต้นแบบอยู่? - person Olical; 14.01.2011
comment
@Martin ถ้าอย่างนั้นอย่าใช้ jQuery อีกเลย มันเต็มไปด้วยการเรียก hasOwnProperty สิ่งที่คุณกำลังทำคือการเพิ่มประสิทธิภาพก่อนกำหนด ไม่มีอะไรอย่างอื่น - person Ivo Wetzel; 14.01.2011
comment
@Wolfy ฉันแค่อยากจะชี้ให้เห็นข้อผิดพลาดที่เป็นไปได้ที่อาจเกิดขึ้นเมื่อโค้ดอื่น (ไม่ว่าจะเป็นของคุณที่คุณเขียนใน 2 สัปดาห์) หรือสคริปต์อื่นที่คุณอาจใช้บนเพจของคุณขยายต้นแบบเนื่องจากสิ่งแปลก ๆ จะจบลงในของคุณ properties วัตถุ - person Ivo Wetzel; 14.01.2011
comment
@Ivo Wetzel โอ้ใช่แล้ว ฉันคิดว่ามันเป็นปัญหากับรหัสปัจจุบันของฉัน และฉันคิดว่าสคริปต์ของฉันใช้งานไม่ได้เนื่องจากไม่มีความยาวและคำสั่ง for in ไม่ทำงานเพราะเหตุนี้ ตอนนี้ฉันรู้แล้วว่าไม่มีอะไรผิดปกติกับวัตถุ คุณรู้ไหมว่าทำไมมันถึงทำให้ความสูงเคลื่อนไหวเท่านั้นมากกว่าทั้งสองอย่าง? - person Olical; 14.01.2011
comment
@Ivo ง่าย ๆ ... ตัวอย่างของคุณดีและคุณพูดถูกมันมีทั้งสายเอี๊ยมและเข็มขัด ไม่มีอะไรผิดปกติ ฉันแค่เร่ขายทางเลือกที่ง่ายกว่าและเร็วกว่า - อย่าถือเป็นเรื่องส่วนตัวที่เรามีความคิดเห็นที่แตกต่างกัน;) - person Martin Jespersen; 14.01.2011
comment
@Wofly คุณต้องส่ง p ลงใน wrapper ภาพเคลื่อนไหวด้วย เช่นเดียวกับ i และ element เนื่องจาก for in loop จะแทนที่ p - person Ivo Wetzel; 14.01.2011
comment
@Ivo แน่นอน! เพราะฉันมีฟังก์ชันภายในฟังก์ชัน ขอบคุณสำหรับสิ่งนั้น! - person Olical; 14.01.2011
comment
วัตถุที่มีลักษณะคล้ายอาร์เรย์ก็มีคุณสมบัติด้านความยาวเช่นกัน :))) แต่ไม่ใช่อาร์เรย์ - person Alexandr; 14.01.2011
comment
@Alexandr แน่นอน แต่มันพยายามหลีกเลี่ยงความสับสนมากกว่านี้ ควรสังเกตด้วยว่าวัตถุ JS จริงเพียงตัวเดียวที่ทำงานเหมือนอาร์เรย์คืออาร์กิวเมนต์ ส่วนที่เหลือเป็นส่วนหนึ่งของ DOM :) - person Ivo Wetzel; 14.01.2011
comment
@Ivo Wetzel แน่นอนคำตอบของคุณ - ยอดเยี่ยมมาก! และเพียงพอแล้วที่จะเข้าใจสาเหตุของปัญหา - person Alexandr; 14.01.2011

สิ่งนี้ได้รับการรองรับใน node.js และสภาพแวดล้อมที่ใหม่กว่า

var obj = {a: "a", b: "b"};
Object.keys(obj).length // 2
person Jamund Ferguson    schedule 06.03.2012
comment
ไม่รองรับ IE8, developer.mozilla .org/en-US/docs/Web/JavaScript/Reference/ - person Igor Parra; 23.02.2015

หากคุณใช้ Underscore.js คุณสามารถใช้ _.size():

_.size({one : 1, two : 2, three : 3});
=> 3
person Casey    schedule 06.03.2012
comment
ฉันยังไม่เห็นแหล่งที่มา แต่ฉันหวังว่า size() จะคำนึงถึง hasOwnProperty - person RaphaelDDL; 10.04.2014

วัตถุไม่มีความยาว คุณจะต้องใช้อาร์เรย์หากต้องการ

หากคุณต้องค้นหาจำนวนคุณสมบัติในวัตถุ มีทางเดียวเท่านั้น:

var length =0;
for(var i in obj) length++;
person Martin Jespersen    schedule 14.01.2011
comment
โปรดใช้ hasOwnProperty - person Ivo Wetzel; 14.01.2011
comment
ทำไมอย่างไร? hasOwnProperty ใช้กับสิ่งนี้ได้ที่ไหน? - person Olical; 14.01.2011
comment
ดีกว่าที่จะ ไม่ อัปเดต Object.prototype หรือไม่ ใครทำอย่างนั้น? นี่เป็นตัวอย่างที่ดีจริงๆ! - person Jamund Ferguson; 06.03.2012
comment
@IvoWetzel ตัวอย่างที่จะได้รับการชื่นชม ฉันใช้คำตอบของ Martin Jespersen ที่นี่ jsfiddle.net/jeykeu/qAH48 มันเป็นหนทางไปหรือเปล่า ? - person Junaid Qadir Shekhanzai; 13.03.2012

นี่คือฟังก์ชันทั่วไปของ @Junaid Qadir Shekhanzai สำหรับ "การค้นหาความยาวของวัตถุ" (ซึ่งดังที่เราบอกไปแล้ว ควรเรียกอย่างถูกต้องว่า "การนับคุณสมบัติของวัตถุ") มันรวมโซลูชั่นจาก @Ivo Wetzel และ @Martin Jespersen:

function countProperties(myObj){
    var length = 0;
    if(typeof myObj != 'object'){
        return false;
    }
    for(var i in myObj) {
    length++;
    }
    return length;
}
person Michael McGinnis    schedule 31.10.2017