I am unable to understand why check corresponding to line if (i in t)
- Line no.18 is placed in filter function polyfill :
if (!Array.prototype.filter) {
Array.prototype.filter = function(fun/*, thisArg*/) {
'use strict';
if (this === void 0 || this === null) {
throw new TypeError();
}
var t = Object(this);
var len = t.length >>> 0;
if (typeof fun !== 'function') {
throw new TypeError();
}
var res = [];
var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
for (var i = 0; i < len; i++) {
if (i in t) {
var val = t[i];
// NOTE: Technically this should Object.defineProperty at
// the next index, as push can be affected by
// properties on Object.prototype and Array.prototype.
// But that method's new, and collisions should be
// rare, so use the more-patible alternative.
if (fun.call(thisArg, val, i, t)) {
res.push(val);
}
}
}
return res;
};
}
I am unable to understand why check corresponding to line if (i in t)
- Line no.18 is placed in filter function polyfill :
if (!Array.prototype.filter) {
Array.prototype.filter = function(fun/*, thisArg*/) {
'use strict';
if (this === void 0 || this === null) {
throw new TypeError();
}
var t = Object(this);
var len = t.length >>> 0;
if (typeof fun !== 'function') {
throw new TypeError();
}
var res = [];
var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
for (var i = 0; i < len; i++) {
if (i in t) {
var val = t[i];
// NOTE: Technically this should Object.defineProperty at
// the next index, as push can be affected by
// properties on Object.prototype and Array.prototype.
// But that method's new, and collisions should be
// rare, so use the more-patible alternative.
if (fun.call(thisArg, val, i, t)) {
res.push(val);
}
}
}
return res;
};
}
Share
edited Dec 29, 2014 at 6:47
thefourtheye
240k53 gold badges465 silver badges500 bronze badges
asked Dec 29, 2014 at 6:37
OptimusOptimus
1161 silver badge7 bronze badges
1
- Do we need to check if (i in t) when we are using a for loop to loop over array elements? – Abhijit Commented May 2, 2020 at 5:30
6 Answers
Reset to default 6It is to avoid the elements which are not defined yet, in the sparse arrays. See the following example,
var array = [];
array[3] = 10;
console.log(array.length);
// 4
So, the length of the array is 4, but only the element at index 3
is defined, all others are not defined yet. So, if you do
for (var i = 0; i < array.length; i += 1) {
console.log(i, array[i]);
}
you will get
0 undefined
1 undefined
2 undefined
3 10
Arrays are special JavaScript objects. The indices are just properties in the array object. Whenever you extend the array object with an index which is not in the array, the length
property will be adjusted internally. In this case, there is only one property in the array object, with the name 3
defined. But we are trying to access elements from 0 to 3. So it returns undefined
for all the indices which are not present in the array object yet.
To avoid that, we are checking if the current index is really defined in the array object, with that if
statement.
for (var i = 0; i < array.length; i += 1) {
if (i in array) {
console.log(i, array[i]);
}
}
would print
3 10
This is because it's possible for JavaScript arrays to have gaps.
For example, consider the following:
var a = ["hello", "howdy", "wele"];
delete greetings[1];
"0" in a; // true
"1" in a; // false
"2" in a; // true
Array.prototype.myFilter = function(callBack) {
let newArray = [];
for (let i = 0; i < this.length; i++) {
let result = callBack(this[i], i, this);
if (result) {
newArray.push(this[i]);
}
}
return newArray;
IN is a reserved keyword which can be used in for and if statement.
18th line they are doing exist check
Refer this dot vs in.
Create own filter()
method
Array.prototype.newFilter = function(func){
let filtered = [], n = this.length;
for(let i = 0; i<n; i++) {
if(func(this[i],i,this))
filtered.push(this[i]);
}
return filtered;
}
let result = [1,2,3,4,5,6,7].newFilter(item => item > 4);
console.log(result);
Array.prototype.myFilter = function(callBackFn) {
let res = [];
if (!Array.isArray(this)) {
throw new Error(`${this} is not a function`);
}
for (let i = 0; i<this.length; i++) {
if (callBackFn(this[i], i, this)) {
res.push(this[i])
}
}
return res
}