Работает ли Object.keys () в Internet Explorer 9 для встроенных объектов? - PullRequest
3 голосов
/ 15 июня 2011

Метод Object.keys () прекрасно работает для меня с таким кодом:

var foo = {foo: 1, bar: 2};
console.log(Object.keys(foo).length);

Однако Object.keys () возвращает массив нулевой длины для встроенных объектов с кодом, подобным следующему:

<!doctype html> 
<html>

<head>

<title>Object.keys()</title>

</head>

<body>
<script type="text/javascript">
console.log(Object.keys(window.document).length);
</script>

</body>

</html>

Я что-то упустил? Я использую Internet Explorer 9.0.8112.16421.

<ч />

Постскриптум: Мне до сих пор не ясно, почему это (например):

    for (prop in performance.timing) {
        if (performance.timing.hasOwnProperty(prop)) {
            console.log(prop); 
        }
    }

... ничего не производит в IE9, тогда как это прекрасно работает:

for (prop in performance.timing) {
    console.log(prop); 
}

1 Ответ

4 голосов
/ 15 июня 2011

В JavaScript есть собственные объекты и хост-объекты . В общем, вы можете положиться на такие вещи, как Object.keys, работающие с нативными объектами, но не с хост-объектами. window, document и другие являются объектами хоста. IE, в частности, хорошо известен своими хост-объектами, не похожими на нативные (у хост-функций нет функции call или apply и т. Д.).

Альтернативно, возможно, что document не имеет перечисляемых свойств. Большинство свойств объектов по умолчанию не перечисляются и поэтому не отображаются в Object.keys. Например, Object.keys([]).length и Object.keys(new RegExp(".*")).length оба являются 0, поскольку ни один из них не имеет никаких перечислимых свойств, даже если они оба имеют много свойств (у них есть свойства для всех их "методов", и, конечно, пустой массив имеет свойство length, а RegExp имеет свойство lastIndex).


Обновление : И на самом деле это была перечисляемая вещь. Попробуйте этот тест:

alert(Object.keys(window.document).length);
window.document.AAA__expando__property = "foo";
alert(Object.keys(window.document).length);

Для меня в IE9 эти оповещения равны «0» и «1» соответственно. Так что window.document поддерживает Object.keys, просто у window.document по умолчанию нет никаких перечисляемых свойств. (В отличие от этого, в Chrome для начала у меня есть 65 перечисляемых свойств и, конечно, 66, когда я добавил свой expando.)

Вот немного более полная тестовая страница ( живая копия ) (быстро взломанная, не самая красивая):

window.onload = function() {

  document.getElementById('theButton').onclick = function() {

    if (typeof Object.keys !== 'function') {
      display("<code>Object.keys</code> is not a function");
      return;
    }
    showKeys("Before adding", Object.keys(window.document));
    window.document.AAAA__expando__foo = "bar";
    showKeys("After adding", Object.keys(window.document));
  };

  function showKeys(prefix, keys) {
    var p, ul;

    keys.sort();
    prefix =
      "[" + prefix +
      "] Keys on <code>window.document</code> (" +
      keys.length +
      ")";
    if (keys.length !== 0) {
      prefix += " (click to toggle list)";
    }
    p = display(prefix);
    if (keys.length !== 0) {
      ul = document.createElement("ul");
      ul.innerHTML = "<li>" + keys.join("</li><li>") + "</li>";
      ul.style.display = "none";
      document.body.appendChild(ul);
      p.onclick = function() {
        ul.style.display =
          (ul.style.display === "none") ? "" : "none";
      };
    }
  }

  function display(msg) {
    var p = document.createElement('p');
    p.innerHTML = msg;
    document.body.appendChild(p);
    return p;
  }

};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...