كيفية بكفاءة الاعتماد على عدد من المفاتيح/خصائص كائن في جافا سكريبت ؟

StackOverflow https://stackoverflow.com/questions/126100

سؤال

ما هي أسرع طريقة لحساب عدد من مفاتيح/خصائص كائن ؟ فإنه من الممكن أن تفعل هذا دون بالتكرار على الكائن ؟ أيدون أن تفعل

var count = 0;
for (k in myobj) if (myobj.hasOwnProperty(k)) count++;

(فايرفوكس لم توفر السحر __count__ مكان الإقامة ، ولكن هذا تم إزالتها في مكان ما حول الإصدار 4.)

هل كانت مفيدة؟

المحلول

للقيام بذلك في أي ES5 المتوافقة مع البيئة, مثل عقدة, كروم, إنترنت إكسبلورر 9+, Firefox 4+ أو سفاري 5+:

Object.keys(obj).length

نصائح أخرى

يمكن استخدام هذه التعليمة البرمجية:

if (!Object.keys) {
    Object.keys = function (obj) {
        var keys = [],
            k;
        for (k in obj) {
            if (Object.prototype.hasOwnProperty.call(obj, k)) {
                keys.push(k);
            }
        }
        return keys;
    };
}

ثم يمكنك استخدام هذا في المتصفحات القديمة وكذلك:

var len = Object.keys(obj).length;

إذا كنت تستخدم Underscore.js يمكنك استخدام _.حجم (شكرا @douwe):
_.size(obj)

بدلا من ذلك يمكنك أيضا استخدام _.مفاتيح والتي قد تكون أكثر وضوحا لبعض:
_.keys(obj).length

أنا أوصي التأكيد ، ضيق مكتبة تفعل الكثير من الأشياء الأساسية.كلما كان ذلك ممكنا أنها مباراة ECMA5 و تؤجل تنفيذ الأصلي.

وإلا الدعم @Avi الجواب.وأنا تحريره لإضافة رابط MDC doc التي تشمل المفاتيح (طريقة) يمكنك إضافتها إلى غير ECMA5 المتصفحات.

مستوى تنفيذ الكائن (ES5.1 الكائن الداخلية الخصائص و الأساليب) لا يحتاج Object لتعقب عدد من مفاتيح/خصائص ، لذلك يجب أن يكون هناك طريقة قياسية لتحديد حجم Object دون صراحة أو ضمنا بالتكرار على مفاتيحها.

حتى هنا هي الأكثر استخداما البدائل:

1.ECMAScript هو كائن.مفاتيح()

Object.keys(obj).length; يعمل عن طريق داخليا بالتكرار على مفاتيح حساب مؤقت مجموعة وإرجاع طوله.

  • الايجابيات للقراءة و نظيفة الجملة.أي مكتبة أو العرف رمز المطلوبة ما عدا الرقائق إذا دعم أصلي غير متوفر
  • سلبيات - الذاكرة العلوية بسبب إنشاء مجموعة.

2.مكتبة الحلول المستندة إلى

العديد من مكتبة يستند إلى أمثلة أخرى في هذا الموضوع مفيدة التعابير في سياق المكتبة.من وجهة نظر ، ومع ذلك ، لا يوجد شيء للحصول على مقارنة الكمال لا رمز المكتبة منذ كل تلك المكتبة أساليب فعلا لتغليف إما عن حلقة أو ES5 Object.keys (الأم أو shimmed).

3.تحسين على حلقة

على أبطأ جزء هذا عن حلقة عموما .hasOwnProperty() الدعوة بسبب استدعاء دالة النفقات العامة.حتى عندما كنت ترغب فقط في عدد الإدخالات من كائن JSON, أنا فقط تخطي .hasOwnProperty() دعوة لو كنت أعرف أن أي رمز لم ولن تمتد Object.prototype.

وإلا التعليمات البرمجية الخاصة بك يمكن أن يكون قليلا جدا من خلال جعل الأمثل k المحلية (var k) و باستخدام البادئة-زيادة المشغل (++count) بدلا من postfix.

var count = 0;
for (var k in myobj) if (myobj.hasOwnProperty(k)) ++count;

فكرة أخرى تعتمد على التخزين المؤقت hasOwnProperty الطريقة:

var hasOwn = Object.prototype.hasOwnProperty;
var count = 0;
for (var k in myobj) if (hasOwn.call(myobj, k)) ++count;

إذا كان هذا هو أسرع أو لا على بيئة معينة هي مسألة القياس.محدودة جدا كسب الأداء يمكن أن يكون من المتوقع على أي حال.

إذا كنت تعمل في الواقع إلى مشكلة أداء أود أن أقترح التفاف المكالمات إضافة/إزالة خصائص/من وجوه مع وظيفة أيضا الزيادات/decrements مناسب اسمه (الحجم؟) مكان الإقامة.

تحتاج فقط إلى حساب العدد الأولي من خصائص مرة واحدة والانتقال من هناك.إذا لم يكن هناك الأداء الفعلي المشكلة, لا تهتم.مجرد التفاف قليلا من التعليمات البرمجية في الدالة getNumberOfProperties(object) وينبغي القيام به معها.

أنا لست على علم بأي طريقة للقيام بذلك ، ومع ذلك للحفاظ على التكرار إلى الحد الأدنى ، قد تتمكن من محاولة التحقق من الوجود __count__ و إذا لم يكن موجودا (أي لا فايرفوكس) ثم هل يمكن أن يكرر أكثر من موضوع تحديد لاستخدامها لاحقا على سبيل المثال:

if (myobj.__count__ === undefined) {
  myobj.__count__ = ...
}

هذه الطريقة أي دعم المتصفح __count__ استخدام هذا التكرار من شأنه أن تتم إلا عن تلك التي لا.إذا كان عدد التغييرات و لا يمكنك فعل هذا, أنت يمكن أن تجعل دائما وظيفة:

if (myobj.__count__ === undefined) {
  myobj.__count__ = function() { return ... }
  myobj.__count__.toString = function() { return this(); }
}

هذه الطريقة في أي وقت يمكنك الرجوع myobj.__count__ الدالة النار حساب.

كما ذكر من قبل Avi الكتان https://stackoverflow.com/a/4889658/1047014

Object.keys(obj).length

سوف تفعل خدعة لجميع خصائص enumerable على وجوه الخاص بك ولكن أيضا تشمل غير enumerable خصائص يمكنك بدلا من ذلك استخدام Object.getOwnPropertyNames.هنا الفرق:

var myObject = new Object();

Object.defineProperty(myObject, "nonEnumerableProp", {
  enumerable: false
});
Object.defineProperty(myObject, "enumerableProp", {
  enumerable: true
});

console.log(Object.getOwnPropertyNames(myObject).length); //outputs 2
console.log(Object.keys(myObject).length); //outputs 1

console.log(myObject.hasOwnProperty("nonEnumerableProp")); //outputs true
console.log(myObject.hasOwnProperty("enumerableProp")); //outputs true

console.log("nonEnumerableProp" in myObject); //outputs true
console.log("enumerableProp" in myObject); //outputs true

كما ذكر هنا وهذا له نفس المتصفح الدعم Object.keys

ومع ذلك, في معظم الحالات, قد لا ترغب في تضمين nonenumerables في هذا النوع من العمليات ، ولكن من الجيد دائما أن تعرف الفرق ;)

تكرار على Avi الكتان الجواب من وجوه.مفاتيح(الكائنات).طول هو الصحيح لكائن التي لا يجب الوظائف المرتبطة به

على سبيل المثال:

obj = {"lol": "what", owo: "pfft"};
Object.keys(obj).length; // should be 2

مقابل

arr = [];
obj = {"lol": "what", owo: "pfft"};
obj.omg = function(){
    _.each(obj, function(a){
        arr.push(a);
    });
};
Object.keys(obj).length; // should be 3 because it looks like this 
/* obj === {"lol": "what", owo: "pfft", omg: function(){_.each(obj, function(a){arr.push(a);});}} */

خطوات لتجنب هذا:

  1. لا تضع في وظائف الكائن الذي تريد حساب عدد المفاتيح في

  2. استخدام منفصلة كائن أو كائن جديد خصيصا وظائف (إذا كنت تريد أن نحصي العديد من الوظائف هناك في الملف باستخدام Object.keys(obj).length)

أيضا نعم لقد استخدمت _ أو تؤكد وحدة من nodejs في بلدي على سبيل المثال

وثائق يمكن العثور عليها هنا http://underscorejs.org/ وكذلك المصدر على github وغيرها من معلومات

وأخيرا lodash تنفيذ https://lodash.com/docs#size

_.size(obj)

بالنسبة لأولئك الذين لديهم Underscore.js المدرجة في المشروع يمكنك القيام به:

_({a:'', b:''}).size() // => 2

أو نمط وظيفي:

_.size({a:'', b:''}) // => 2

من: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

الكائن.defineProperty(obj, دعامة, واصف)

يمكنك إما إضافة إلى جميع الأشياء الخاصة بك:

Object.defineProperty(Object.prototype, "length", {
    enumerable: false,
    get: function() {
        return Object.keys(this).length;
    }
});

أو كائن واحد:

var myObj = {};
Object.defineProperty(myObj, "length", {
    enumerable: false,
    get: function() {
        return Object.keys(this).length;
    }
});

على سبيل المثال:

var myObj = {};
myObj.name  = "John Doe";
myObj.email = "leaked@example.com";
myObj.length; //output: 2

وأضاف أن الطريق لن يكون عرض له في الحلقات:

for(var i in myObj) {
     console.log(i + ":" + myObj[i]);
}

الإخراج:

name:John Doe
email:leaked@example.com

ملاحظة:أنها لا تعمل في < IE9 المتصفحات.

كما أجاب أعلاه: Object.keys(obj).length

ولكن:كما لدينا الآن حقيقي خريطة الدرجة في ES6 ، وأود أن أقترح لاستخدامها بدلا من استخدام خصائص كائن.

const map = new Map();
map.set("key", "value");
map.size; // THE fastest way

كيف أحل هذه المشكلة هو بناء بلدي تنفيذ القائمة الأساسية التي يحتفظ بسجل كم عدد العناصر المخزنة في الجسم.دورته بسيطة جدا.شيء من هذا القبيل:

function BasicList()
{
   var items = {};
   this.count = 0;

   this.add = function(index, item)
   {
      items[index] = item;
      this.count++;
   }

   this.remove = function (index)
   {
      delete items[index];
      this.count--;
   }

   this.get = function(index)
   {
      if (undefined === index)
        return items;
      else
        return items[index];
   }
}

لتلك التي لديها Ext JS 4 في المشروع يمكنك القيام به:

Ext.Object.getSize(myobj);

ميزة هذا الوضع هو أنه سوف يعمل على كل تحويلة متوافق مع المتصفحات (IE6-IE8 شمل) ، ومع ذلك ، أعتقد أن الوقت يعمل ليس أفضل من O(n) على الرغم كما هو الحال مع غيرها من الحلول المقترحة.

يمكنك استخدام Object.keys(data).length العثور على طول كائن JSON وجود البيانات الرئيسية

إذا مسج أعلاه لا يعمل, ثم حاول

$(Object.Item).length

المرجع لم تحدد إذا كان الكائن هو nodeList ، إذا كان ثم يمكنك فقط استخدام طول طريقة على ذلك مباشرة.على سبيل المثال:

buttons = document.querySelectorAll('[id=button)) {
console.log('Found ' + buttons.length + ' on the screen'); 

أنا لا أعتقد أن هذا ممكن (على الأقل ليس دون استخدام بعض الداخلية).و لا أعتقد أنك قد تكسب الكثير من خلال تحسين هذا.

أنا في محاولة لجعلها متاحة على جميع وجوه مثل هذا:

Object.defineProperty(Object.prototype, "length", {
get() {
    if (!Object.keys) {
        Object.keys = function (obj) {
            var keys = [],k;
            for (k in obj) {
                if (Object.prototype.hasOwnProperty.call(obj, k)) {
                    keys.push(k);
                }
            }
            return keys;
        };
    }
    return Object.keys(this).length;
},});

console.log({"Name":"Joe","Age":26}.length) //returns 2

جوجل إغلاق لطيفة وظيفة هذا...goog.الكائن.getCount(الكائنات)

انظر goog.كائن الوثائق

يمكنك استخدام: Object.keys(objectName).length; & Object.values(objectName).length;

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top