Introduction
In this article I wanted to share with you with the most popular JavaScript methods but implemented by scratch.
A little understanding of how JavaScript methods works inside will always help you as a developer.
So these are the most popular methods in JavaScript implemented from scratch. Check this out if you are interested how JavaScript methods works inside. This is also a light version of how this work, the real method specified in ECMAScript is much more complex.
Methods mentioned on this article are:
map, reduce, filter, sort, every, includes, slice, splice, shift, indexOf.
1. map()
const fakeMap = function (callback) {
const newArray = [];
// 'this' refers to the array
for (let i = 0; i < this.length; i++) {
newArray[i] = callback(this[i], i);
}
return newArray;
};
Array.prototype.fakeMap = fakeMap;
[1, 2, 3].fakeMap((n) => n + 1); // output [2, 3, 4]
2. reduce()
const fakeReduce = function (callback, accumulator) {
for (let i = 0; i < this.length; i++) {
accumulator = callback(accumulator, this[i]);
}
return accumulator;
};
Array.prototype.fakeReduce = fakeReduce;
const reducer = (previousValue, currentValue) => previousValue + currentValue;
[1, 2, 3].fakeReduce(reducer, 0); // output 6
3. filter()
const fakeFilter = function (callback) {
const newArray = [];
for (let i = 0; i < this.length; i++) {
if (callback(this[i])) {
newArray.push(this[i]);
}
}
return newArray;
};
Array.prototype.fakeFilter = fakeFilter;
[1, 2, 3, 4, 5].fakeFilter((n) => n > 2); // output [3, 4, 5]
4. sort()
const fakeSort = function (callback) {
const newArray = [...this];
for (let i = 0; i < newArray.length; i++) {
for (let j = 0; j < newArray.length - 1; j++) {
if (callback(newArray[j], newArray[j + 1]) > 0) {
const temp = newArray[j + 1];
newArray[j + 1] = newArray[j];
newArray[j] = temp;
}
}
}
// array is sorted
return newArray;
};
Array.prototype.fakeSort = fakeSort;
[3, 5, 1, 4, 2].fakeSort((a, b) => a - b); // output [1, 2, 3, 4, 5]
5. every()
const fakeEvery = function (callback) {
for (let i = 0; i < this.length; i++) {
if (!callback(this[i])) {
return false;
}
}
return true;
};
Array.prototype.fakeEvery = fakeEvery;
[1, 2, 3, 4, 5].fakeEvery((n) => n > 3); // output false
6. includes()
const fakeIncludes = function (item) {
for (let i = 0; i < this.length; i++) {
if (this[i] === item) {
return true;
}
}
return false;
};
Array.prototype.fakeIncludes = fakeIncludes;
[1, 2, 3, 4, 5].fakeIncludes(5); // output true
7. slice()
const fakeSlice = function (start, end) {
let newArray = [];
if (!end) {
for (let i = 0; i < this.length; i++) {
if (i >= start) {
newArray.push(this[i]);
}
}
return newArray;
}
for (let i = 0; i < this.length; i++) {
if (i >= start && i <= end) {
newArray.push(this[i]);
}
}
return newArray;
};
Array.prototype.fakeSlice = fakeSlice;
[1, 2, 3, 4, 5].fakeSlice(2, 3); // output [3, 4]
8. splice()
const fakeSplice = function (start, deleteCount, ...items) {
let newArray = [];
// if we only provide start fakeSplice(start)
if (!deleteCount) {
for (let i = 0; i < this.length; i++) {
if (i < start) {
newArray.push(this[i]);
}
}
this.length = 0;
this.push.apply(this, newArray);
return;
}
// if we only provide start and deleteCount fakeSplice(start, deleteCount)
if (!items) {
for (let i = 0; i < this.length; i++) {
if (i < start || i >= start + deleteCount) {
newArray.push(this[i]);
}
}
this.length = 0;
this.push.apply(this, newArray);
return;
}
// if we provide all arguments to the function
for (let i = 0; i < this.length; i++) {
if (i === start + deleteCount) {
newArray = [...newArray, ...items];
}
if (i < start || i >= start + deleteCount) {
newArray.push(this[i]);
}
}
this.length = 0;
this.push.apply(this, newArray);
return;
};
Array.prototype.fakeSplice = fakeSplice;
const planets = [
"Mercury",
"Venus",
"Earth",
"Mars",
"Jupiter",
"Saturn",
"Uranus",
"Neptune",
];
planets.fakeSplice(2, 2, "Pluto");
console.log(planets); // output ["Mercury", "Venus", "Pluto", "Jupiter", "Saturn", "Uranus", "Neptune"]
9. shift()
const fakeShift = function () {
let newArray = [];
for (let i = 1; i < this.length; i++) {
newArray.push(this[i]);
}
this.length = 0;
this.push.apply(this, newArray);
};
Array.prototype.fakeShift = fakeShift;
const arr = [1, 2, 3, 4, 5];
arr.fakeShift();
console.log(arr); // output [2, 3, 4, 5]
10. indexOf()
const fakeIndexOf = function (item) {
for (let i = 0; i < this.length; i++) {
if (item === this[i]) {
return i;
}
}
return -1;
};
Array.prototype.fakeIndexOf = fakeIndexOf;
[1, 2, 3, 4, 5].fakeIndexOf(4); // output 3
Conclusion
We just implemented the most used methods in JavaScript and get a better understanding of how they work so we can use them more effectively.
Thank you for your time!
Top comments (21)
Not really π ... is like saying that knowing asm makes you a better dev. If you know how to use this methods, the underlying implementation doesn't matter much. Don't get me wrong, is fine if you implement this kind of things manually for fun, but my point is that is not that useful in "the real world". Other than that, you should avoid messing with native objects prototypes ... and you could also implement some of this methods with
for...of
, so for examplemap
could be:Cheers!
Yes, I totally agree with you.
You don't have to know how car engine works inside to drive a car, what I meant was
knowing how car engine works, makes you a better understanding of a car itself.
And you may be surprised but assembly language is still in use, so knowing such stuff definitely makes you a better dev π.
Cheers!
COBOL is also in still in use, that doesn't mean you need to learn it to be a better WebDev π ... and that analogy with the car doesn't apply here, because you don't debug the internals of
Array.prototype.map
(the engine), you just debug the usage of map. The folks working on the browser engine are the ones dealing with "the engine" πThese are only a light versions of "the engine". So we won't get a full understanding of it, but a light one.
For those who want to familiarize with the internals of JS methods e.g.
Array.prototype.map
you can find this information here: developer.mozilla.org/en-US/docs/W...Thanks π
It's not the same thing as rebuilding a car engine, but it shows he knows javascript and datastructure. Sometimes you need an original algorithm if you software is a bit innovative, if you just do lame integration work then it's ok you don't need to understand much.
It's ok to know how things work, but my point is that is not necessary and it doesn't make you a "better developer". Maybe if we were talking about a low level language, but re-implementing
Array.prototype.map
in JavaScript is kinda pointless. Is way more useful that you know when and how to use those methods, that if you know how they work internally.Not only that, if you see questions like this in an interview for a JavaScript/TypeScript position, take that as a π© red flag π© and get out of there.
I don't say ALL integration work are lame, I say that there are integration work that are lame that's why they are automatable why do you think lowcode/nocode are now rising and usable by just business people ;) dev.to/lepinekong/comment/1l7ab
If you want to discuss no-code, then let's do it in there, this thread is about the need for developers to know about the underlying implementation of native methods, which from my point of view is pointless ... and if you bring no-code to the table, that feels more like an argument in favor of my point of view, tbh.
I also gave my two cents on that post about no-code, so if you want to discuss that topic further, feel free to do it there.
I do SystemThinking : things are not separate ;) If I recruit a coder I will indeed want to be sure he master the fundamentals if not I would rather recruit the guy/girl for doing lowcode or nocode.
If you did β¨ community moderation β¨ you'll consider that talking about unrelated topics is πspamπ (Just think about the author receiving notifications about something unrelated to their post) .... I guess we can leave it at "we agree to disagree".
It's not my fault if you are narrow minded, just a joke also if you don't mind ;)
sort
should work in place:tc39.es/ecma262/#sec-array.prototy...
developer.mozilla.org/en-US/docs/W...
Hi!
These are only a light versions of popular methods in JS, and of course the original methods mentioned in ECMAScript are much more complex and useful.
Thank you for comment :)
Nice. Fundamentals are worth knowing. Developers are like engineers who build engines, so if you donβt understand how a single part of the engine you want to build works, than you are going to be some kind of mere dev because trial and error are what you are going to be on all times.
Useful
Good article, but you forgot to include the
return -1
for.indexOf
Thanks for noticing! I made an update.
Good try but most of the Algorithms are wayyyyyy too slow to use, for example, your sort algorithm is taking O(N^2) time too slow.
As ECMAScript doesnβt specify any sorting algorithm to be implemented by
Array.prototype.sort()
, it totally depends on browser which sorting algorithm to be implement.Safari, Webkit, etc. uses 'Selection Sort' whereas Mozilla uses 'Merge Sort'.
The sorting algorithm behind
.fakeSort()
mentioned in this article is 'Bubble Sort', and is intended for educational purposes and isnβt an efficient method for sorting in real world.Bubble Sort also is one of the most widely discussed algorithms, simply because of its lack of efficiency for sorting arrays. If an array is already sorted, Bubble Sort will only pass through the array once, however the worst case scenario is a run time of O(NΒ²), which is extremely inefficient.
Nice Post
Are these implementations faster than native ones?
Some comments may only be visible to logged-in visitors. Sign in to view all comments. Some comments have been hidden by the post's author - find out more