Собственные объекты JavaScript с расширенным прототипом и циклом for-in

Я продлил Array прототип:

if(typeof Array.prototype.filter === 'undefined') Array.prototype.filter = function(fun /*, thisp*/){
  var len = this.length;
  if(typeof fun != "function") throw new TypeError();

  var res = [], thisp = arguments[1];

  for(var i=0;i<len;i++){
    if(i in this){
      var val = this[i]; // in case fun mutates this
      if(fun.call(thisp, val, i, this)) res.push(val);
    }
  }

  return res;
};

Например, я создал массив:

var A = [ 1, 2, 3, 4, 5 ];

Затем я добавил дополнительные свойства, которые я буду использовать:

A.creator = 'Rustam';
A.created = new Date();

Если я буду использовать for-in цикл, и браузер не имеет встроенной поддержки Array.filter, это пройдет A.filter,

Я знаю так:

for(var p in A) {
  if (!A.hasOwnProperty(p)) continue
  console.log(p)
};

Есть ли способ сделать A.filter спрятано в for-in без использования hasOwnProperty ?


ОБНОВЛЕНИЕ, чтобы ответить. Поддержка браузера:

  • IE9 +
  • FF4 +
  • Хром
  • Опера 11.6+
  • Safari 5+

1 ответ

Решение

Чтобы определить свойство, которое не отображается в циклах, используйте Object.defineProperty:

Object.defineProperty(Array.prototype, 'filter', {value:'XYZ'});

Это расширяет Array.prototype со свойством под названием filter с дескрипторами свойств по умолчанию, в том числе enumerable: false что приводит к тому, что свойство не отображается в for( .. in ..) петли.

Рекомендации

PS: не будет работать в старых браузерах. У меня нет матрицы совместимости браузеров для этого API.

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