Помогите понять пример hasOwnProperty()

170
28 декабря 2018, 16:00

Читаю книгу по JavaScript'у, там такого рода пример:

Object.prototype.keys = function() { 
  var keys = []; 
  for(var p in this) keys.push(p); 
  return keys; 
} 
 
var obj = {a: 1, b: 2, c: 3}; 
 
if(obj.keys().length == 3) { 
  alert(1); 
} else { 
  alert(2) 
}

Суть заключается в том, что свойство length не работает по какой-то причине корректно и я не могу понять по какой.

Далее дается следующий пример, где добавляют проверку:

Object.prototype.keys = function() { 
  var keys = []; 
  for(var p in this)  
   if (this.hasOwnProperty(p)) keys.push(p); 
  return keys; 
} 
 
var obj = {a: 1, b: 2, c: 3}; 
 
if(obj.keys().length == 3) { 
  alert(1); 
} else { 
  alert(2) 
}

Не могу понять, как данная проверка повлияла на результат выполнения.

В моем понимании, во втором примере, идет проверка, унаследовано ли свойство у объекта или нет, и если нет, то оно добавляется в массив с результатами, а если да, то не добавляется. Но в тестовом объекте нет унаследованных свойств, по сути результат один и тот же должен выйти, но это не так. Объясните пожалуйста.

Answer 1

Ошибка станет яснее, если вывести результат вызова keys().

Object.prototype.keys = function() { 
  var keys = []; 
  for (var p in this) keys.push(p); 
  return keys; 
} 
 
var obj = { 
  a: 1, 
  b: 2, 
  c: 3 
}; 
 
console.log(obj.keys());

Как видно, новый метод keys так же записывается.

Чтобы он не учитывался, нужно изменить ему модификатор enumerable на false

Убедиться что оно true можно получив описание свойства, поменять существующее свойство либо создать новое можно с помощью метода Object.defineProperty

Object.prototype.keys = function() { 
  var keys = []; 
  for (var p in this) keys.push(p); 
  return keys; 
} 
var keysProp = Object.getOwnPropertyDescriptor(Object.prototype, 'keys'); 
console.log(keysProp); 
 
keysProp.enumerable = false; 
 
// меняем существующее свойство 
Object.defineProperty(Object.prototype, 'keys', keysProp); 
var obj = { 
  a: 1, 
  b: 2, 
  c: 3 
}; 
 
console.log(obj.keys());
.as-console-wrapper { 
  max-height: none !important; 
}

Подробнее про обход с помощью For..in можно увидеть в вопросе: По какому принципу цикл FOR IN обходит массив?

Answer 2

В первом случае keys содержит и методы и свойства (3 свойства и сам метод keys), и имеет длину 4. Во втором случае keys содержит только свойства, и имеет длину 3.

READ ALSO
Функция вкладок навигации

Функция вкладок навигации

Есть функция, которая меняет блоки при нажатии на вкладку навигации

176
Почему setInterval быстрее?

Почему setInterval быстрее?

Есть два бегуна:

151
Как сделать сортировку массива по дате?

Как сделать сортировку массива по дате?

каждый блок это 1 el-container есть вот такой массив

164