Как исправить недостающие ключи в Object.keys() по сравнению с for... в hasOwnProperty()

В некоторых браузерах (Chrome, Safari) Object.keys() не возвращает все ключи, которые в цикле for-in hasOwnProperty() возвращается.

Есть ли обходной путь без использования петель for-in?

Также есть другой объект, чем window который показывает ту же ошибку или это только проблема с window объект, как показывают мои тесты?

осветление

Оба должны возвращать только собственные и только перечислимые свойства, как мы можем прочитать из документации:

Вывод: они должны повторять одни и те же ключи: только перечислимые и собственные свойства.

Результаты поиска

1) Firefox 39: нет отсутствующего ключа

2) Chromium 38: 47 недостающих ключей:

["speechSynthesis", "localStorage", "sessionStorage", "applicationCache", "webkitStorageInfo", "indexedDB", "webkitIndexedDB", "crypto", "CSS", "performance", "console", "devicePixelRatio", "styleMedia", "parent", "opener", "frames", "self", "defaultstatus", "defaultStatus", "status", "name", "length", "closed", "pageYOffset", "pageXOffset", "scrollY", "scrollX", "screenTop", "screenLeft", "screenY", "screenX", "innerWidth", "innerHeight", "outerWidth", "outerHeight", "offscreenBuffering", "frameElement", "clientInformation", "navigator", "toolbar", "statusbar", "scrollbars", "personalbar", "menubar", "locationbar", "history", "screen"]

3) Safari 5.1: 37 недостающих ключей:

["open", "moveBy", "find", "resizeTo", "clearTimeout", "btoa", "getComputedStyle", "setTimeout", "scrollBy", "print", "resizeBy", "atob", "openDatabase", "moveTo", "scroll", "confirm", "getMatchedCSSRules", "showModalDialog", "close", "clearInterval", "webkitConvertPointFromNodeToPage", "matchMedia", "prompt", "focus", "blur", "scrollTo", "removeEventListener", "postMessage", "setInterval", "getSelection", "alert", "stop", "webkitConvertPointFromPageToNode", "addEventListener", "dispatchEvent", "captureEvents", "releaseEvents"]

Тестовый скрипт

var res = (function(obj) {
    var hasOwn = Object.prototype.hasOwnProperty;

    var allKeys = [];
    for(var key in obj) {
        if(hasOwn.call(obj, key)) {
            allKeys.push(key);
        }
    }

    var keys = Object.keys(obj);

    var missingKeys = [];
    for(var i = 0; i < allKeys.length; i++) {
        if(keys.indexOf(allKeys[i]) === -1) {
            missingKeys.push(allKeys[i]);
        }
    }

    return {allKeys: allKeys, keys: keys, missingKeys: missingKeys};
})(window);

// This should be empty if the followings return the same set of keys:
// - for...in with hasOwnProperty()
// - Object.keys()
console.log(res.missingKeys, res.missingKeys.length);

0 ответов

Другие вопросы по тегам