What does Name[proto][push] do? in js - javascript

I found this piece of code which seems pretty cool. I see return new Set(array); written so i know set is a class. But what does Set[proto] mean and what does [push] mean and .pop and why is
one a dot while the other is in square brace.
Also arguments[length] looks pretty cool. I imagine its an implicit parameter in each func? i am not sure how length works in this case. This looks really cool and i am very much a newbie at JS.
// Set
var Set = function (items) {
this.items = [];
this[length] = 0;
this.type = "set";
if (items) {
for (var i = 0, ii = items[length]; i < ii; i++) {
if (items[i] && (items[i].constructor == Element || items[i].constructor == Set)) {
this[this.items[length]] = this.items[this.items[length]] = items[i];
this[length]++;
}
}
}
};
Set[proto][push] = function () {
var item,
len;
for (var i = 0, ii = arguments[length]; i < ii; i++) {
item = arguments[i];
if (item && (item.constructor == Element || item.constructor == Set)) {
len = this.items[length];
this[len] = this.items[len] = item;
this[length]++;
}
}
return this;
};
Set[proto].pop = function () {
delete this[this[length]--];
return this.items.pop();
};

In that code the proto variable is set to the string "prototype", and the push variable is set to "push". So, Set[proto] is the same as saying Set.prototype.
So this:
Set[proto][push]
is the same as:
Set.prototype.push
The code is actually creating a function on the Set's prototype called push. A functions prototype is an object that all instances constructed from that function inherit.
For more information about prototype property read this

Related

Javascript create array in for loop

I'm pretty sure this is a basic question but my PHP background is making me unable to solve this. I was also unable to find a solution that came even close in SO.
I have an array of objects containing a value I want to loop and sum. Everything works well but I would like to directly sum those values to another array in the output.
So this is the working function:
function postsCalc(arrayEntry) {
var postsOutput = [];
var postLikes = 0;
for (var i = 0, len = arrayEntry.length; i < len; i++) {
postLikes += arrayEntry[i].likes.summary.total_count;
}
postsOutput.likes = postLikes;
return postsOutput;
}
Output:
likes : 55555;
Which works well, but can't I push it directly to the array key and avoid having to do the postsOutput.likes = postLikes?
Like this:
function postsCalc(arrayEntry) {
var postsOutput = [];
for (var i = 0, len = arrayEntry.length; i < len; i++) {
postsOutput.likes += arrayEntry[i].likes.summary.total_count;
// or even a multidimensional:
postsOutput.totals.likes += arrayEntry[i].likes.summary.total_count;
}
return postsOutput;
}
and that would output the same as above but avoiding the extra step, is this possible in Javascript?
Thanks in advance
You can use the reduce function on a list to do this:
function postsCalc(arrayEntry) {
var postLikes = arrayEntry.reduce(function(a, b) {return a + b.likes.summary.total_count}, 0);
return {likes: postLikes};
}
It works like this: Array.reduce(callback, initialValue) where callback = function(a, b) where a is the accumulator (e.g. tracks the sum, etc) and b is a representation of the item you're iterating over on the list. initialValue is the starting point for the function (e.g. on the first iteration).
Idiomatic javascript would look like (for your first function):
function postsCalc(arrayEntry) {
var postsOutput = {
postLikes: 0
};
for (var i = 0, len = arrayEntry.length; i < len; i++) {
postsOutput.postLikes += arrayEntry[i].likes.summary.total_count;
}
return postsOutput;
}
or, now that we can assume .forEach exists:
function postsCalc(arrayEntry) {
var postsOutput = {
postLikes: 0
};
arrayEntry.forEach(function(entry) {
postsOutput.postLikes += entry.likes.summary.total_count;
}
return postsOutput;
}

Javascript filter function polyfill

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-compatible alternative.
if (fun.call(thisArg, val, i, t)) {
res.push(val);
}
}
}
return res;
};
}
It 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", "welcome"];
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
}

Run functions that are stored in an array

I am pushing some functions into an array but I am not sure how to run the functions as I loop through the array.
I am trying to get red yellow green to output to the console.
Here is a fiddle to my JavaScript: http://jsfiddle.net/rYNv4/
Here is the code that I have so far as well:
var myArr = [];
myArr.push( logItRunner('red') );
myArr.push( logItRunner('yellow') );
myArr.push( logItRunner('green') );
console.log(myArr);
//Function to be stored in array. Should return the logIt function.
function logItRunner( arg ) {
return function() {
logIt( arg );
};
}
//Function to log a string to the console
function logIt (color) {
console.log(color);
};
//Function to loop through array and fire functions within the array
function runIt () {
for (var i = 0, len = myArr.length; i < len; i++) {
//Fire Function within Array at position i and log the argument to the console.
myArr[i];
};
};
runIt();
myArr[i] is a function reference. You call the function it refers to just like you do any other time you have a function reference, with ():
In your loop, change:
myArr[i];
to
myArr[i]();
See how I'm executing the myArri; below.
You've almost got it, you just forgot the ().
//Function to loop through array and fire functions within the array
function runIt () {
for (var i = 0, len = myArr.length; i < len; i++) {
//Fire Function within Array at position i and log the argument to the console.
myArr[i]();
};
};
It is all about how JavaScript closures work, this usually is the way we teach JavaScript closures, so your sample is a good one, since it clarifies the concept.
This is the way I usually do the exact same thing to teach JavaScript closures, which is completely similar to yours with some little differences:
var myArr = [];
myArr.push('red');
myArr.push('yellow');
myArr.push('green');
var funcArr=[];
function pushIt () {
for (var i = 0, len = myArr.length; i < len; i++) {
var func = (function(color){
return (function(){
console.log(color);
});
})(myArr[i]);
funcArr.push(func);
};
};
function runIt () {
for (var i = 0, len = funcArr.length; i < len; i++) {
funcArr[i]();
};
};
pushIt();
runIt();

How to prototype a duplicate prototype method for Array in javascript

I'm trying to implement a duplicate method to the js Array prototype which concats a duplicate of the array to itself like so:
[11,22,3,34,5,26,7,8,9].duplicate(); // [11,22,3,34,5,26,7,8,9,11,22,3,34,5,26,7,8,9]
Here's what I have, but it causes the browser to crash:
var array = [11,22,3,34,5,26,7,8,9];
Array.prototype.duplicate = function() {
var j = this.length;
for(var i = 0; i < this.length; i++) {
this[j] = this[i];
j++;
}
return this;
}
I'm trying to do this using native JS as practice for iterations and algorithms so I'm trying to avoid built-in methods, if possible, so that I can get a clearer understanding of how things are being moved around.
Any ideas on why it is crashing and how I can optimize it?
The code inside the loop changes the length of the array, so it will just keep growing and you will never reach the end of it. Get the initial length of the array in a variable and use in the loop condition. You can use that as offset for the target index also instead of another counter:
var array = [11,22,3,34,5,26,7,8,9];
Array.prototype.duplicate = function() {
var len = this.length;
for (var i = 0; i < len; i++) {
this[len + i] = this[i];
}
return this;
}
The length of the array is increasing with each element added so you can not use this as a terminator. Try this.
var j = this.length;
for(var i = 0; i < j; i++) {
this[i+j] = this[i];
}
Here's simplest code
Array.prototype.duplicate = function () {
var array = this;
return array.concat(array);
};
Using Spread syntax;
In a method, this refers to the owner object.
Array.prototype.duplicate = function () {
return [...this, ...this]
};
let array = [1,2,3,4,5];
Array.prototype.duplicate = function () {
return [...this, ...this]
};
console.log(array.duplicate());

How to check an array if it contains a string in Javascript?

I have an array that contains string.
var js_userBoxName = new Array();
I want to search the elements of the array if a string has the word "foo" it should displayed.
So for example my array contains the words {foofy, foofa, foo, awtsy}, foofy, foofa and foo will be displayed since they all contains the word foo.
Check out the Array.filter method:
var arr = ['foofy', 'foofa', 'foo', 'awtsy'];
var fooItems = arr.filter(function (item) {
return item.indexOf('foo') >= 0;
});
// Yields ['foofy', 'foofa', 'foo']
The linked MDN page contains a polyfill for browsers that do not support it. If you happen to be using jQuery, you could use $.grep:
var arr = ['foofy', 'foofa', 'foo', 'awtsy'];
var fooItems = $.grep(arr, function (item) {
return item.indexOf('foo') >= 0;
});
You could also try this:
var myarray = ["foofy", "foofa", "foo", "awtsy"];
var searched_string = "foo";
var foundmatch = [];
for(i=0; i < myarray.length; i++){
if(myarray[i].match(searched_string)){
foundmatch.push(myarray[i]);
}
}
alert(foundmatch);
NOTE: Good performance tip is to always cache the length of your array when iterating over it rather than recalculating it for each loop execution. len = js_userBoxName.length
http://jsperf.com/caching-array-length/4
function () {
for(var i = 0, len = js_userBoxName.length; i < len; i++){
if(typeof js_userBoxName[i] === 'string'){
if(js_userBoxName[i].indexOf('foo') == -1)
return true;
}
}
return false;
}
The following function should do the trick, it uses only standard acme script elements
function Find (myarray, searchterm){
for (var i=0, len = myarray.length; i<len; i += 1){
if (typeof(myarray[i]) === 'string' && myarray[i].search(searchterm) !== -1){
// print or whatever
//hint use a callback here that you pass in as an additional arugment
}
}
}
using search allows you to use regex if you need to check for something more complex
The following should work:
var myArray = ['foofy', 'foofa', 'foo', 'awtsy'];
for ( var i = 0; i < myArray.length; i++ ) {
if ( myArray[i].contains('foo') )
console.log(myArray[i]);
}
prints:
foofy
foofa
foo
Note: "awtsy" does not contain the pattern foo

Categories