จะแสดงรายการคุณสมบัติของวัตถุ JavaScript ได้อย่างไร


842

พูดว่าฉันสร้างวัตถุดังนี้:

var myObject =
        {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};

วิธีที่ดีที่สุดในการเรียกรายการชื่อคุณสมบัติคืออะไร เช่นฉันต้องการจะจบลงด้วย 'ปุ่ม' ตัวแปรบางอย่างที่:

keys == ["ircEvent", "method", "regex"]

3
หัวข้อออกไปเล็กน้อย แต่ถ้าคุณใช้ underscore.js:_.keys(myJSONObject)
Endy Tjahjono

คำตอบ:


1076

ในเบราว์เซอร์สมัยใหม่ (IE9 +, FF4 +, Chrome5 +, Opera12 +, Safari5 +) คุณสามารถใช้เมธอดObject.keysในตัว :

var keys = Object.keys(myObject);

ด้านบนมี polyfill เต็มรูปแบบ แต่เวอร์ชันที่ง่ายคือ:

var getKeys = function(obj){
   var keys = [];
   for(var key in obj){
      keys.push(key);
   }
   return keys;
}

หรือแทนที่var getKeysด้วยObject.prototype.keysเพื่ออนุญาตให้คุณโทรหา.keys()วัตถุใดก็ได้ การขยายต้นแบบมีผลข้างเคียงบางอย่างและฉันไม่แนะนำให้ทำ


17
ฉันจะอัปเดตอีกครั้งกับเอฟเฟกต์ 'คุณอาจถูกล่อลวงให้ทำเช่นนี้กับ object ต้นแบบ ... แต่อย่า!'
AnthonyWJones

4
จะมีใครต้องการเปิดไฟทำไมมันไม่แนะนำให้เพิ่มฟังก์ชั่นต้นแบบของวัตถุ?
Vishwanath

2
นั่นเป็นคำถามที่แตกต่างกันโดยสิ้นเชิงเกี่ยวกับตัวเองการค้นหาอย่างรวดเร็วที่นี่ใน stackoverflow หรือบน Google จะให้คุณอ่านมากมาย
ximi

3
for (var key in myObject) {...}เทคนิคจะเป็นประโยชน์สำหรับ runtimes จาวาสคริปต์ด้านนอกของเบราว์เซอร์และ V8 ตัวอย่างเช่นเมื่อผ่าน javascript map-ลดการสืบค้นลงใน Riak Objectวัตถุไม่มีอยู่ดังนั้นจึงไม่มีObject.keysวิธีการดังกล่าว
ekillaby

19
@slashnick "เวอร์ชันที่ทำให้เข้าใจง่าย" ของคุณจะส่งคืนคุณสมบัติทั้งหมดในห่วงโซ่ต้นแบบของวัตถุ (เนื่องจากใช้ "สำหรับ ... ใน") ในขณะที่วิธี (ECMAScript 5.1) Object.keysจะส่งกลับคุณสมบัติของวัตถุเท่านั้น ฉันเห็นว่ามันเป็นความแตกต่างที่สำคัญ
Martin Carel

255

ในฐานะที่เป็นslashnickชี้ให้เห็นคุณสามารถใช้โครงสร้าง "for in" เพื่อวนซ้ำวัตถุสำหรับชื่อแอตทริบิวต์ อย่างไรก็ตามคุณจะวนซ้ำชื่อแอตทริบิวต์ทั้งหมดในห่วงโซ่ต้นแบบของวัตถุ หากคุณต้องการที่จะย้ำเพียงกว่าคุณลักษณะของตัวเองของวัตถุที่คุณสามารถทำให้การใช้งานของวัตถุ # hasOwnProperty ()วิธีการ จึงมีดังต่อไปนี้

for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
        /* useful code here */
    }
}

25
ฉันหวังว่าฉันได้อ่านเรื่องนี้ก่อนคำตอบของ slashnic ข้างต้น ฉันต้องใช้เวลา 15 นาทีในการกดescปุ่มค้างไว้เพราะวัตถุมีคุณสมบัติเป็นล้านคุณสมบัติส่วนใหญ่ไม่ได้ใช้และฉันได้รับการแจ้งเตือน
Mark Henderson

นี่เป็นบทความที่ยอดเยี่ยมเกี่ยวกับเรื่องของ Zakas เอง: nczonline.net/blog/2010/07/27/…
Pablo Cabrera

4
ฮ่า ๆ @MarkHenderson - แต่ครั้งต่อไปเพียงแค่ฆ่ากระบวนการเบราว์เซอร์และเริ่มต้นใหม่แทนที่จะเสีย 15 นาที :)
JD สมิ ธ

ฟังก์ชั่นที่เกี่ยวข้องคือ obj.getOwnPropertyNames () - developer.mozilla.org/en-US/docs/JavaScript/Reference/
Steve Goodman

@MarkHenderson ทำไมคุณไม่ใช้ console.log
LasagnaAndroid

102

ดังที่ Sam Dutton ตอบวิธีการใหม่สำหรับจุดประสงค์นี้ได้ถูกนำเสนอใน ECMAScript 5th Edition Object.keys()จะทำในสิ่งที่คุณต้องการและได้รับการสนับสนุนในFirefox 4 , 6 Chrome, Safari 5 และIE 9

นอกจากนี้คุณยังสามารถใช้วิธีในเบราว์เซอร์ที่ไม่รองรับได้อย่างง่ายดาย อย่างไรก็ตามการนำไปใช้งานบางอย่างนั้นไม่สามารถทำงานร่วมกับ Internet Explorer ได้อย่างสมบูรณ์ นี่คือโซลูชันที่เข้ากันได้มากขึ้น:

Object.keys = Object.keys || (function () {
    var hasOwnProperty = Object.prototype.hasOwnProperty,
        hasDontEnumBug = !{toString:null}.propertyIsEnumerable("toString"),
        DontEnums = [ 
            'toString', 'toLocaleString', 'valueOf', 'hasOwnProperty',
            'isPrototypeOf', 'propertyIsEnumerable', 'constructor'
        ],
        DontEnumsLength = DontEnums.length;

    return function (o) {
        if (typeof o != "object" && typeof o != "function" || o === null)
            throw new TypeError("Object.keys called on a non-object");

        var result = [];
        for (var name in o) {
            if (hasOwnProperty.call(o, name))
                result.push(name);
        }

        if (hasDontEnumBug) {
            for (var i = 0; i < DontEnumsLength; i++) {
                if (hasOwnProperty.call(o, DontEnums[i]))
                    result.push(DontEnums[i]);
            }   
        }

        return result;
    };
})();

โปรดทราบว่าคำตอบที่ได้รับการยอมรับในปัจจุบันไม่ได้รวมการตรวจสอบสำหรับhasOwnProperty ()และจะส่งคืนคุณสมบัติที่สืบทอดผ่านห่วงโซ่ต้นแบบ นอกจากนี้ยังไม่ได้อธิบายถึงข้อบกพร่อง DontEnum ที่มีชื่อเสียงใน Internet Explorer ที่คุณสมบัติที่ไม่นับบนเชนต้นแบบทำให้คุณสมบัติที่ประกาศในเครื่องมีชื่อเดียวกันเพื่อสืบทอดแอตทริบิวต์ DontEnum ของพวกเขา

การใช้งานObject.keys ()จะช่วยให้คุณมีโซลูชั่นที่แข็งแกร่งยิ่งขึ้น

แก้ไข:ต่อไปนี้การอภิปรายที่ผ่านมากับkangax , ผู้บริจาคที่รู้จักกันดีต้นแบบผมดำเนินการแก้ปัญหาสำหรับข้อผิดพลาด DontEnum ตามรหัสของเขาObject.forIn()ฟังก์ชั่นที่พบที่นี่


คำตอบที่ดีฉันคิดว่าคำตอบที่ยอมรับยังคงเป็นคำตอบที่แม่นยำที่สุดโดยถือว่าเป็นคำสั่ง JSON เสมอ นี่คือสิ่งที่จะใช้ในที่อื่นอย่างแน่นอน
David Snabel-Caunt

1
@David Caunt: ขอบคุณ :-) น่าเสียดายที่คำตอบที่ยอมรับยังคงผิดพลาดข้อผิดพลาดของ DontEnum และคุณไม่เคยรู้เลยว่าวัตถุ JSON ใดที่อาจมีสตริงเช่น "valueOf" หรือ "constructor" เป็นหนึ่งในกุญแจ Object.prototypeนอกจากนี้ยังจะย้ำไปขยาย แต่บ่อยครั้งที่รหัสที่สั้นกว่านั้นดูน่าดึงดูดกว่าโค้ดที่ใหญ่กว่าและมีความทนทานมากกว่า แต่จุดสำคัญของคำตอบนี้คือการใช้ ECMAScript 5th's Object.keys()ซึ่งสามารถนำไปใช้ในเบราว์เซอร์ที่ไม่รองรับโค้ดนี้ได้ เวอร์ชั่นเนทีฟจะมีประสิทธิภาพมากกว่านี้
Andy E

2
ดีมากแอนดี้ :) ฉันอยากจะเตือน - ไม่มีใครพูดถึงในหัวข้อนี้ - ว่า ES5 Object.keysจะส่งกลับอาร์เรย์ของสตริงที่สอดคล้องกับคุณสมบัติที่นับไม่ได้ของวัตถุ สิ่งนี้อาจไม่สำคัญเมื่อทำงานกับวัตถุดั้งเดิม (ผู้ใช้กำหนดเอง) แต่ควรมองเห็นได้ดีกับวัตถุโฮสต์ (แม้ว่าพฤติกรรมวัตถุโฮสต์ที่ไม่ได้ระบุเป็นเรื่องที่แยกจากกัน - เจ็บปวด -) ในการแจกแจงคุณสมบัติทั้งหมด (รวมถึงคุณสมบัติที่ไม่นับได้) ES5 ให้Object.getOwnPropertyNames(ดูการสนับสนุนในตาราง compat ของฉัน - kangax.github.com/es5-compat-table )
kangax

2
ฉันได้รวมโซลูชันนี้ไว้ใน es5-shim github.com/kriskowal/es5-shim/blob/master/es5-shim.js#L390
Kris Kowal

2
บางคนสามารถอธิบายได้ว่าทำไมสิ่งนี้ถึงถูกนำมาใช้เป็นObject.keys(stuff)และไม่stuff.keys()?
Blazemonger

32

โปรดทราบว่า Object.keys และวิธีการ ECMAScript 5 อื่น ๆ รองรับ Firefox 4, Chrome 6, Safari 5, IE 9 ขึ้นไป

ตัวอย่างเช่น:

var o = {"foo": 1, "bar": 2}; 
alert(Object.keys(o));

ตารางความเข้ากันได้ ECMAScript 5: http://kangax.github.com/es5-compat-table/

คำอธิบายวิธีการใหม่: http://markcaudill.com/index.php/2009/04/javascript-new-features-ecma5/


ตรวจสอบคีย์ () ในคอนโซลสำหรับ Chrome Dev Tools, Firebug และอื่น ๆ อีกมากมาย
Sam Dutton


28

Object.getOwnPropertyNames(obj)

Object.keys(obj)ฟังก์ชั่นนี้ยังแสดงให้เห็นคุณสมบัติที่ไม่นับนอกเหนือจากที่แสดงโดย

ใน JS enumerableคุณสมบัติทุกคนมีคุณสมบัติไม่กี่รวมทั้งบูล

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

ตัวอย่าง:

var o = Object.create({base:0})
Object.defineProperty(o, 'yes', {enumerable: true})
Object.defineProperty(o, 'not', {enumerable: false})

console.log(Object.getOwnPropertyNames(o))
// [ 'yes', 'not' ]

console.log(Object.keys(o))
// [ 'yes' ]

for (var x in o)
    console.log(x)
// yes, base

ยังทราบวิธีการ:

  • Object.getOwnPropertyNamesและObject.keys อย่าขึ้นไปตามสายโซ่ต้นแบบเพื่อค้นหาbase
  • for in ทำ

เพิ่มเติมเกี่ยวกับต้นแบบลูกโซ่ที่นี่: https://stackoverflow.com/a/23877420/895245


16

ฉันเป็นแฟนตัวยงของฟังก์ชั่นการถ่ายโอนข้อมูล

http://ajaxian.com/archives/javascript-variable-dump-in-coldfusion ข้อความแสดงแทน


1
+1 เพราะฉันมาที่นี่เพื่อสร้างสิ่งที่คล้ายกัน (แม้ว่าจะไม่ดีเท่านี้)
Camilo Martin

1
netgrow.com.au/assets/files/dump/dump.zipไม่พบ ฉันจะดาวน์โหลด javascript dump ได้อย่างไร
Kiquenet

@Kiquenet ทุกครั้งที่ผมอยากจะสร้างบางสิ่งบางอย่างที่ฉันชำระนี้สำหรับการตรวจสอบวัตถุปกติถ้าคุณต้องการที่แสดงผลในรูปแบบ HTML มีสิ่งที่ต้องการโมดูล NPM สิ่งที่ทำให้ฉันติดอยู่คือฉันต้องการสิ่งที่ดีกว่าสิ่งที่อยู่ในภาพ แต่ไม่เคยคิดที่จะคิด มันมีความสุภาพในการเรียกดูวัตถุในตัวตรวจสอบ แต่ฮิวริสติกพยายามและอนุมานความหมายจากวัตถุที่กำหนดเอง (เช่นการเรียงลำดับอาร์เรย์ของวัตถุลงในตารางที่มีคอลัมน์) ไม่สามารถใช้งานได้จริง
Camilo Martin

เกี่ยวกับPretty Print Javascript https://j11y.io/demos/prettyprint/คืออะไร?
Kiquenet

13

สามารถทำได้ด้วย jQuery ดังต่อไปนี้:

var objectKeys = $.map(object, function(value, key) {
  return key;
});

9

หากคุณพยายามที่จะได้รับองค์ประกอบเท่านั้น แต่ไม่ใช่ฟังก์ชั่นแล้วรหัสนี้สามารถช่วยคุณได้

this.getKeys = function() {

    var keys = new Array();
    for(var key in this) {

        if( typeof this[key] !== 'function') {

            keys.push(key);
        }
    }
    return keys;
}

นี่เป็นส่วนหนึ่งของการใช้งาน HashMap ของฉันและฉันต้องการแค่ปุ่มเท่านั้น "นี่" เป็นวัตถุ hashmap ที่มีกุญแจ


8

สิ่งนี้จะใช้ได้กับเบราว์เซอร์ส่วนใหญ่แม้แต่ใน IE8 และไม่จำเป็นต้องใช้ไลบรารีใด ๆ var i เป็นกุญแจสำคัญของคุณ

var myJSONObject =  {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"}; 
var keys=[];
for (var i in myJSONObject ) { keys.push(i); }
alert(keys);

2
คำตอบของคุณคล้ายกับคำตอบที่โพสต์ไปแล้วมีอะไรให้เพิ่มอีกบ้าง?
VKen


7

Mozilla มีรายละเอียดการติดตั้งอย่างสมบูรณ์เกี่ยวกับวิธีการใช้งานในเบราว์เซอร์ที่ไม่รองรับหากสิ่งนั้นช่วย:

if (!Object.keys) {
  Object.keys = (function () {
    var hasOwnProperty = Object.prototype.hasOwnProperty,
        hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
        dontEnums = [
          'toString',
          'toLocaleString',
          'valueOf',
          'hasOwnProperty',
          'isPrototypeOf',
          'propertyIsEnumerable',
          'constructor'
        ],
        dontEnumsLength = dontEnums.length;

    return function (obj) {
      if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) throw new TypeError('Object.keys called on non-object');

      var result = [];

      for (var prop in obj) {
        if (hasOwnProperty.call(obj, prop)) result.push(prop);
      }

      if (hasDontEnumBug) {
        for (var i=0; i < dontEnumsLength; i++) {
          if (hasOwnProperty.call(obj, dontEnums[i])) result.push(dontEnums[i]);
        }
      }
      return result;
    };
  })();
}

คุณสามารถรวมมันได้ตามต้องการ แต่อาจอยู่ในextensions.jsไฟล์บางประเภทที่ด้านบนสุดของสคริปต์สแต็กของคุณ


การติดตั้ง MDN นั้นขึ้นอยู่กับ Andy E ซึ่งได้รับคำตอบแล้ว
outis

5

ใช้ Reflect.ownKeys()

var obj = {a: 1, b: 2, c: 3};
Reflect.ownKeys(obj) // ["a", "b", "c"]

Object.keysและObject.getOwnPropertyNamesไม่สามารถรับคุณสมบัติที่ไม่นับได้ มันทำงานได้แม้กับคุณสมบัติที่ไม่นับ

var obj = {a: 1, b: 2, c: 3};
obj[Symbol()] = 4;
Reflect.ownKeys(obj) // ["a", "b", "c", Symbol()]

4

IE ไม่รองรับ (i in obj) สำหรับคุณสมบัติดั้งเดิม นี่คือรายการอุปกรณ์ประกอบฉากทั้งหมดที่ฉันสามารถหาได้

ดูเหมือนว่า stackoverflow ทำการกรองโง่ ๆ

รายการมีอยู่ที่ด้านล่างของโพสต์กลุ่ม google นี้: - https://groups.google.com/group/hackvertor/browse_thread/thread/a9ba81ca642a63e0


4

เนื่องจากฉันใช้underscore.jsในเกือบทุกโครงการฉันจะใช้keysฟังก์ชัน:

var obj = {name: 'gach', hello: 'world'};
console.log(_.keys(obj));

ผลลัพธ์ของสิ่งนั้นจะเป็น:

['name', 'hello']

เป็นไลบรารีชุดเครื่องมือสำหรับการใช้งานจาวาสคริปต์ที่ใช้บ่อย: underscorejs.org
schmijos

4

การสร้างคำตอบที่ได้รับการยอมรับ

ถ้า Object มีคุณสมบัติที่คุณต้องการเรียกใช้ say .properties () ลอง!

var keys = Object.keys(myJSONObject);

for (var j=0; j < keys.length; j++) {
  Object[keys[j]].properties();
}

0

โซลูชันทำงานกับเคสและเบราว์เซอร์ของฉัน:

var getKeys = function(obj) {
    var type = typeof  obj;
    var isObjectType = type === 'function' || type === 'object' || !!obj;

    // 1
    if(isObjectType) {
        return Object.keys(obj);
    }

    // 2
    var keys = [];
    for(var i in obj) {
        if(obj.hasOwnProperty(i)) {
            keys.push(i)
        }
    }
    if(keys.length) {
        return keys;
    }

    // 3 - bug for ie9 <
    var hasEnumbug = !{toString: null}.propertyIsEnumerable('toString');
    if(hasEnumbug) {
        var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
            'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];

        var nonEnumIdx = nonEnumerableProps.length;

        while (nonEnumIdx--) {
            var prop = nonEnumerableProps[nonEnumIdx];
            if (Object.prototype.hasOwnProperty.call(obj, prop)) {
                keys.push(prop);
            }
        }

    }

    return keys;
};
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.