จะตรวจสอบว่า object มีคุณสมบัติใด ๆ ใน JavaScript ได้อย่างไร


167

สมมติว่าฉันประกาศ

var ad = {}; 

ฉันจะตรวจสอบว่าวัตถุนี้จะมีคุณสมบัติที่ผู้ใช้กำหนดได้อย่างไร

คำตอบ:


86

คุณสามารถวนซ้ำคุณสมบัติของวัตถุของคุณดังนี้:

for(var prop in ad) {
    if (ad.hasOwnProperty(prop)) {
        // handle prop as required
    }
}

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

แก้ไข

จากความคิดเห็น: คุณสามารถใส่รหัสนั้นในฟังก์ชั่นและทำให้มันกลับเท็จทันทีที่มันมาถึงส่วนที่มีความคิดเห็น

การทดสอบประสิทธิภาพ

การทดสอบของวัตถุคีย์เทียบกับ .. ในเมื่อทดสอบคุณสมบัติใด ๆ


2
สวัสดี Daniel จริง ๆ แล้วฉันกำลังมองหาอุปกรณ์เพื่อตรวจสอบว่าวัตถุมีคุณสมบัติที่ผู้ใช้กำหนดเองหรือไม่ ไม่ตรวจสอบว่ามีคุณสมบัติเฉพาะอยู่หรือไม่
Ricky

7
@Ricky: คุณสามารถใส่รหัสนั้นในฟังก์ชั่นและทำให้มันกลับเท็จทันทีที่มันมาถึงส่วนที่มีความคิดเห็น
Daniel Vassallo

8
ฉันคิดว่าการใช้วันนี้Object.keysเป็นสิ่งที่ง่ายที่สุด: var a = [1,2,3];a.something=4;console.log(Object.keys(a))เนื่องจากเป็นส่วนหนึ่งของ ECMA 5 อยู่แล้วคุณจึงสามารถควบคุมได้อย่างปลอดภัย: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/ …
HMR

2
โปรดทราบว่า "วันนี้" กับ ES5 Object.defineProperty(obj, 'foo', {enumerable:false, value:'foo'})วัตถุพื้นเมืองสามารถมีคุณสมบัติที่ไม่นับตัวเองเช่น
RobG

2
วิธีนี้เป็นวิธีการตรวจสอบกุญแจที่มีอยู่แต่คำตอบที่ถูกต้องมีประสิทธิภาพและถูกต้องที่สุดอยู่ด้านล่างโดยใช้ Object.keys (x) .length คุณไม่จำเป็นต้องทำให้ฟังก์ชั่นของคุณเองมีอยู่แล้ว!
dudewad

193

คุณสามารถใช้Object.keysวิธีการบิวด์อินเพื่อรับรายการคีย์บนวัตถุและทดสอบความยาว

var x = {};
// some code where value of x changes and than you want to check whether it is null or some object with values

if(Object.keys(x).length > 0){
 // Your code here if x has some properties  
}

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

6
Object.keys ( "myString"); ให้คีย์เช่นกันซึ่งฉันคิดว่าไม่เป็นที่พึงปรารถนา คำตอบนี้ไม่สมบูรณ์ในความคิดของฉัน
Mike de Klerk

2
@ MikedeKlerk โปรดอ่านอย่างระมัดระวังไม่ใช่ Object.keys ("mystring"); เป็น Object.keys (objectVariableName) ซึ่งจะส่งกลับอาร์เรย์ของคีย์ทั้งหมดในวัตถุ ตัวอย่าง: {'x': 'abc', 'y': 'def'} มันจะเป็น ['x', 'y']
Dhaval Chaudhary

3
@DhavalChaudhary ขอบคุณสำหรับการตอบกลับความคิดเห็นของฉัน เมื่อฉันลองใช้รหัสนี้var str = "MyString"; Object.keys(str);คอนโซลเอาต์พุต 8 คีย์จาก 0 ถึง 7 สำหรับแต่ละอักขระ หรือฉันยังไม่เข้าใจคำตอบ
Mike de Klerk

6
@ MikedeKlerk แต่มันเป็นเพียงทางออกสำหรับวัตถุที่ไม่ได้สำหรับสตริงกรุณาดูคำถาม
Dhaval Chaudhary

111

แล้วการทำฟังก์ชั่นง่าย ๆ ล่ะ?

function isEmptyObject(obj) {
  for(var prop in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, prop)) {
      return false;
    }
  }
  return true;
}

isEmptyObject({}); // true
isEmptyObject({foo:'bar'});  // false

hasOwnPropertyเรียกวิธีโดยตรงบนObject.prototypeเป็นเพียงการเพิ่มเล็ก ๆ น้อย ๆความปลอดภัยจินตนาการต่อไปนี้ใช้ปกติobj.hasOwnProperty(...)โทร:

isEmptyObject({hasOwnProperty:'boom'});  // false

หมายเหตุ: (สำหรับอนาคต) วิธีการข้างต้นขึ้นอยู่กับfor...inคำสั่งและคำสั่งนี้ iterates เฉพาะคุณสมบัติที่นับไม่ได้ในปัจจุบัน ECMAScript Standard (ฉบับที่ 3) ที่ใช้กันอย่างแพร่หลายในปัจจุบันโปรแกรมเมอร์ไม่มีวิธีใด ๆ ในการสร้างคุณสมบัติที่ไม่นับ .

อย่างไรก็ตามสิ่งนี้ได้เปลี่ยนไปแล้วด้วยECMAScript 5th Editionและเราสามารถสร้างคุณสมบัติที่ไม่นับเขียนไม่ได้หรือไม่สามารถลบได้ดังนั้นวิธีการด้านบนอาจล้มเหลวได้เช่น:

var obj = {};
Object.defineProperty(obj, 'test', { value: 'testVal', 
  enumerable: false,
  writable: true,
  configurable: true
});
isEmptyObject(obj); // true, wrong!!
obj.hasOwnProperty('test'); // true, the property exist!!

โซลูชัน ECMAScript 5 สำหรับปัญหานี้จะเป็น:

function isEmptyObject(obj) {
  return Object.getOwnPropertyNames(obj).length === 0;
}

Object.getOwnPropertyNamesวิธีการส่งกลับArrayมีชื่อของทุกคุณสมบัติของตัวเองของวัตถุนับหรือไม่วิธีนี้จะถูกดำเนินการในขณะนี้โดยผู้ขายเบราว์เซอร์มันมีอยู่แล้วบน Chrome Beta 5 และล่าสุด WebKit คืนสร้าง

Object.defineProperty ยังมีอยู่ในเบราว์เซอร์เหล่านั้นและ Firefox 3.7 Alpha รุ่นล่าสุด


1
ประโยชน์ของ Object.prototype.hasOwnProperty.call (obj, prop) เหนือ obj.hasOwnProperty (prop) คืออะไร
Casey Chu

3
@Casey, แก้ไข, ถ้าวัตถุลบล้างhasOwnPropertyคุณสมบัติ, ฟังก์ชันอาจผิดพลาด ... ฉันรู้ว่าฉันหวาดระแวงนิดหน่อย ... แต่บางครั้งคุณก็ไม่รู้ว่าจะใช้รหัสของคุณในสภาพแวดล้อมแบบใด แต่ คุณรู้วิธีการสิ่งที่คุณต้องการที่จะใช้ ...
CMS

2
+1 สำหรับการตอบคำถามนี้ ... และคำถามอื่น ๆ ในอนาคต! :)
Daniel Vassallo

1
หมายเหตุนอกจากนี้ยังมีข้อผิดพลาดใน IE ที่ถ้าคุณมีคุณสมบัติที่มีชื่อที่ตรงกับคุณสมบัติที่ไม่นับในก็ไม่ได้รับการแจกแจงObject.prototype for...inดังนั้นisEmptyObject({toString:1})จะล้มเหลว นี่คือหนึ่งในเหตุผลที่โชคร้ายที่คุณไม่สามารถค่อนข้างใช้Objectเป็นแผนที่วัตถุประสงค์ทั่วไป
bobince

1
@ MichaelMartin-Smucker- ปุ่มจะส่งคืนเฉพาะคุณสมบัติของตัวเองเท่านั้นดังนั้นจึงไม่เหมาะที่นี่
RobG

58

ด้วยjQueryคุณสามารถใช้:

$.isEmptyObject(obj); // Returns: Boolean

ในฐานะของ jQuery 1.4 วิธีการนี้จะตรวจสอบคุณสมบัติทั้งบนวัตถุและคุณสมบัติที่สืบทอดมาจากต้นแบบ (ซึ่งไม่ได้ใช้ hasOwnProperty)

ด้วยECMAScript 5th Editionในเบราว์เซอร์ที่ทันสมัย ​​(IE9 +, FF4 +, Chrome5 +, Opera12 +, Safari5 +) คุณสามารถใช้วิธีการในObject.keys :

var obj = { blah: 1 };
var isEmpty = !Object.keys(obj).length;

หรือ JavaScript เก่าแบบธรรมดา:

var isEmpty = function(obj) {
               for(var p in obj){
                  return false;
               }
               return true;
            };

33

เบราว์เซอร์ล่าสุด (และ node.js) รองรับ Object.keys () ซึ่งส่งกลับอาร์เรย์พร้อมกับคีย์ทั้งหมดในวัตถุตามตัวอักษรของคุณดังนั้นคุณสามารถทำสิ่งต่อไปนี้:

var ad = {}; 
Object.keys(ad).length;//this will be 0 in this case

รองรับเบราว์เซอร์: Firefox 4, Chrome 5, Internet Explorer 9, Opera 12, Safari 5

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys


13

หากคุณใช้ underscore.js คุณสามารถใช้ฟังก์ชัน_.isEmpty :

var obj = {};
var emptyObject = _.isEmpty(obj);

1
สำหรับทุกคนที่ผ่านไปแล้วนี่ไม่ใช่วิธีการเฉพาะสำหรับวัตถุ _.isEmpty([]) // true อย่าลืมตรวจสอบก่อน: stackoverflow.com/a/22482737/1922747
djv

11

หากคุณยินดีที่จะใช้lodashคุณสามารถใช้someวิธีการ

_.some(obj) // returns true or false

ดูตัวอย่าง jsbin ขนาดเล็กนี้


var x = [1,2] // จริง
djv

@damionjn ฉันเพิ่มรหัสของคุณในตัวอย่าง ฉันเห็นจุดของคุณพร้อมอาเรย์คืนคำตอบที่ผิด แต่ OP เริ่มประกาศตัวแปรเป็นวัตถุดังนั้นฉันเชื่อว่ามันไม่เป็นไรที่จะรับสิ่งนี้ มีคำตอบข้างต้นซึ่งใช้วิธีการขีดล่าง isEmpty (lodash มีวิธีการเดียวกัน) คำตอบนั้นมีปัญหาเดียวกันแน่นอน ถ้าคุณให้ isEmpty อาร์เรย์ว่างที่ไม่ว่างคุณจะได้ผลลัพธ์ที่ผิดด้วย
sfs

ยุติธรรมเพียงพอ แต่เราควรจะให้คำตอบกับฐานทั้งหมดที่ครอบคลุมเพื่อให้แน่ใจว่าแนวทางปฏิบัติที่ดีที่สุด คุณพูดถูกฉันตอบถูกโดยไม่มีคำวิจารณ์ใด ๆ สำหรับทุกคนที่ผ่านไปแล้วนี่ไม่ใช่วิธีการเฉพาะสำหรับวัตถุ _.some([1, 2]) // true อย่าลืมตรวจสอบก่อน: stackoverflow.com/a/13356338/1922747
djv

5
for (var hasProperties in ad) break;
if (hasProperties)
    ... // ad has properties

หากคุณจะต้องปลอดภัยและตรวจสอบวัตถุต้นแบบ (สิ่งเหล่านี้จะถูกเพิ่มโดยห้องสมุดบางแห่งและไม่มีตามค่าเริ่มต้น):

var hasProperties = false;
for (var x in ad) {
    if (ad.hasOwnProperty(x)) {
        hasProperties = true;
        break;
    }
}
if (hasProperties)
    ... // ad has properties

1
ในโซลูชันของคุณไม่มีการกรองสำหรับคุณสมบัติต้นแบบที่ไม่ต้องการซึ่งหมายความว่าอาจมีการทำงานผิดพลาดเมื่อใช้ไลบรารีเช่น Prototype.js หรือผู้ใช้ที่ไม่มีประสบการณ์เพิ่มคุณสมบัติต้นแบบเพิ่มเติมลงในวัตถุ ลองใช้โซลูชันของแดเนียลในหน้านี้
Joscha

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

2
for(var memberName in ad)
{
  //Member Name: memberName
  //Member Value: ad[memberName]
}

Member หมายถึงคุณสมบัติสมาชิกตัวแปรสมาชิกไม่ว่าคุณต้องการเรียกมันว่าอะไร> _>

โค้ดด้านบนจะกลับมาทุกอย่างรวมถึง toString ... หากคุณต้องการดูว่าต้นแบบของวัตถุได้รับการขยาย:

var dummyObj = {};  
for(var memberName in ad)
{
  if(typeof(dummyObj[memberName]) == typeof(ad[memberName])) continue; //note A
  //Member Name: memberName
  //Member Value: ad[memberName]

}

หมายเหตุ: เราตรวจสอบเพื่อดูว่าสมาชิกของวัตถุจำลองมีประเภทเดียวกันกับสมาชิกของวัตถุทดสอบของเราหรือไม่ ถ้าเป็นการขยายประเภทสมาชิกของ dummyobject ควรเป็น "undefined"


สวัสดีฉันสามารถรู้ได้ว่าวัตถุมีคุณสมบัติหรือไม่? ขอบคุณ
Ricky

ในโซลูชันของคุณไม่มีการกรองสำหรับคุณสมบัติต้นแบบที่ไม่ต้องการซึ่งหมายความว่าอาจมีการทำงานผิดพลาดเมื่อใช้ไลบรารีเช่น Prototype.js หรือผู้ใช้ที่ไม่มีประสบการณ์เพิ่มคุณสมบัติต้นแบบเพิ่มเติมลงในวัตถุ
Joscha

ลองดูโซลูชันของ Daniels ในหน้านี้ - ข้อผิดพลาดน้อยกว่า!
Joscha

2
บล็อกรหัสแรกของคุณไม่ครอบคลุมเลย บล็อกรหัสที่สองทำงานผิดปกติหากฉันเพิ่มตัวแปรลงในวัตถุ "โฆษณา" ซึ่งไม่ได้กำหนดไว้ จริงๆลองดูคำตอบของแดเนียลส์มันเป็นคำตอบเดียวที่ถูกต้องและรวดเร็วเนื่องจากใช้การติดตั้งแบบดั้งเดิมที่เรียกว่า "hasOwnProperty"
Joscha

@Ricky: ถ้าคุณต้องการที่จะตรวจสอบว่าวัตถุที่มีคุณสมบัติที่คุณสามารถเพียงแค่ใช้ตัวอย่างในคำตอบของฉัน: stackoverflow.com/questions/2673121/... หากรหัสถึงความคิดเห็นวัตถุของคุณจะไม่มีคุณสมบัติโดยตรง ถ้าไม่มันจะ
Daniel Vassallo

2
var hasAnyProps = false; for (var key in obj) { hasAnyProps = true; break; }
// as of this line hasAnyProps will show Boolean whether or not any iterable props exist

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


1

คำตอบที่ล่าช้ามาก แต่นี่เป็นวิธีที่คุณสามารถจัดการกับต้นแบบได้

Array.prototype.Any = function(func) {
    return this.some(func || function(x) { return x });
}

Object.prototype.IsAny = function() {
    return Object.keys(this).Any();
}

0

เมื่อแน่ใจว่าวัตถุนั้นเป็นวัตถุที่ผู้ใช้กำหนดวิธีที่ง่ายที่สุดในการพิจารณาว่า UDO ว่างเปล่าหรือไม่จะเป็นรหัสต่อไปนี้:

isEmpty=
/*b.b Troy III p.a.e*/
function(x,p){for(p in x)return!1;return!0};

แม้ว่าวิธีนี้จะเป็นวิธีการนิรนัย (โดยธรรมชาติ) แต่ก็เป็นวิธีที่เร็วที่สุดและเร็วที่สุด

a={};
isEmpty(a) >> true

a.b=1
isEmpty(a) >> false 

ps: อย่าใช้กับวัตถุที่กำหนดโดยเบราว์เซอร์


... ส่งคืน 0; ส่งคืน 1}; จะเหมือนกันหรือไม่
commonpike

1
@pike no, return! 1; return! 0 เหมือนกับ return false; return true
Christophe

0

ตอบล่าช้า แต่เฟรมเวิร์กบางตัวจัดการวัตถุเป็นแบบนับได้ ดังนั้นbob.jsสามารถทำได้เช่นนี้:

var objToTest = {};
var propertyCount = bob.collections.extend(objToTest).count();

0

คุณสามารถใช้สิ่งต่อไปนี้:

ดับเบิลปัง !! ค้นหาอสังหาริมทรัพย์

var a = !![]; // true
var a = !!null; // false

hasOwnProperty นี่คือสิ่งที่ฉันเคยใช้:

var myObject = {
  name: 'John',
  address: null
};
if (myObject.hasOwnProperty('address')) { // true
  // do something if it exists.
}

อย่างไรก็ตาม JavaScript ตัดสินใจที่จะไม่ปกป้องชื่อของวิธีการดังนั้นจึงสามารถแก้ไขได้

var myObject = {
  hasOwnProperty: 'I will populate it myself!'
};

ประคับประคองใน myObject

var myObject = {
  name: 'John',
  address: null,
  developer: false
};
'developer' in myObject; // true, remember it's looking for exists, not value.

ประเภทของ

if (typeof myObject.name !== 'undefined') {
  // do something
}

อย่างไรก็ตามมันไม่ได้ตรวจสอบค่าว่าง

ฉันคิดว่านี่เป็นวิธีที่ดีที่สุด

ในผู้ประกอบการ

var myObject = {
  name: 'John',
  address: null
};

if('name' in myObject) {
  console.log("Name exists in myObject");
}else{
  console.log("Name does not exist in myObject");
}

ผลลัพธ์:

มีชื่ออยู่ใน myObject

นี่คือลิงค์ที่ให้รายละเอียดเพิ่มเติมเกี่ยวกับตัวดำเนินการ in: การพิจารณาว่ามีคุณสมบัติของวัตถุอยู่หรือไม่


0

ฟังก์ชั่นES6

/**
 * Returns true if an object is empty.
 * @param  {*} obj the object to test
 * @return {boolean} returns true if object is empty, otherwise returns false
 */
const pureObjectIsEmpty = obj => obj && obj.constructor === Object && Object.keys(obj).length === 0

ตัวอย่าง:


let obj = "this is an object with String constructor"
console.log(pureObjectIsEmpty(obj)) // empty? true

obj = {}
console.log(pureObjectIsEmpty(obj)) // empty? true

obj = []
console.log(pureObjectIsEmpty(obj)) // empty? true

obj = [{prop:"value"}]
console.log(pureObjectIsEmpty(obj)) // empty? true

obj = {prop:"value"}
console.log(pureObjectIsEmpty(obj)) // empty? false

-1

แล้วเรื่องนี้ล่ะ

var obj = {},
var isEmpty = !obj;
var hasContent = !!obj

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

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