What are the practical uses of the new methods ES5 provides? - javascript

With libraries such as ES5-Shim, we can use the new hotness now. Many methods on arrays (like forEach, map, every, etc) could be used now to write clean and beautiful code.
I'd like to have a list a practical uses I can have right now with those new methods when working with the current browsers' API (such as the DOM) or with just javascript.
I'm talking about this kind:
var nodes = document.getElementsByClassName('class')
[].forEach.call(nodes, callback)
function callback(node) {
console.log(node)
}
Another example from #Esailija:
[].filter.call( document.myform.elements, function(input){
return input.type == "text";
});
This is the kind of practical use I'm looking for. Some kind of patterns I'd be able to use in real projects.

The first thing you really will be able to use is the bind() method, I think.
var o = {
act: function() { ...}
}
// Instead of
element.addEventListener("type", function(){ o.act(); }, false)
// you can write
element.addEventListener("type", o.act.bind(o), false)
which is very useful in namespaced modules, where this is everything.
The array iterator methods are useful everywhery when it comes to data handling. No specific examples.

You can use iterator functions to manipulate lists.
So before you used for or while loops and now you use functions.
function isTextNode(node) {
return node.nodeType === Node.TEXT_NODE
}
function extractText(node) {
return node.data
}
function combineText(memo, text) {
return memo += text
}
var text = toArray(nodeList).filter(isTextNode).map(extractText).reduce(combineText)
To get used to "how or why this is useful" stop using for/while and think of your data as sets or lists and think about how you would filter / map / reduce these lists to extract data.
Also make an exercise to not use closures and have your iterator functions seperate and not bound over upvalues.

Related

Is there a way to extend an array of JavaScript objects?

In JavaScript you can extend the functionality of an object with prototype.
Person.prototype.fullName = function () {
return this.first + this.last;
};
I run into scenarios a lot where I need to process something on an array of specific objects. These are cases where it would be nice for the functionality to be linked to that object type, as opposed to just passing as an array parameter. I am aware that it is unadvised to extend the JavaScript Array.
Is there an equivalent standard to extend the functionality of an array of objects? Here is a pseudo-example of what I mean:
Person(Array).prototype.groupByAges = function () {
// logic here that would group by ages
// { '0-15': [person, person], '16-18': [person, person], etc. }
return list;
};
// could be used like this
const list = persons.groupByAges();
What I have tried:
writing functions like getAgeGroupsByPerson(arr) which end up cluttering code
JQuery.grep() and JavaScript arr.map() which help but does not link the functionality to that specific object type.
Note: I realize that there may be better ways to logically solve the specific age grouping problem that I have described. It is just an example to demonstrate my point. Thank you.
I see two different approaches that would satisfy your requirements
1) Write a class that extends Array and stick your array in there
class MyArray extends Array {
groupByAge() {
console.log(this);
}
}
let a = MyArray.from([1,2,3]);
a.groupByAge();
2) Write a normal function that takes an array of your objects and does work on it.
function groupByAge(array) {
console.log(this);
}
There is more work than payoff to try to extend a new Array function IMO than doing both of the above. If JS classes isn't something you can utilize then I'd suggest going for the function and just call that "everywhere".
Upside to both approaches is that they are quite easily testable and that's something that we want.
You can decorate your arrays
let decorate = (array) => {
array.groupByAges = function() {
console.log(`Grouping = ${this}`);
}
return array;
}
decorate([1,2,3]).groupByAges();

Sequence of functions applied to a string in functional style

I am trying to understand the ways of using functional style in JavaScript in practice. I've created a simple set of functions to process a string, but I feel I am doing it conceptually wrong because it looks just like imperative style, even though I don't mutate input and don't change state of the app inside the functions.
Here is how it looks:
var LineParser = require('../modules/LineParser');
var inputLine = 'A line with multiple spaces';
var outputLine = LineParser().formatSpaces(inputLine);
// 'A line with multiple spaces'
outputLine = LineParser().capitalize(outputLine);
// 'A Line With Multiple Spaces'
outputLine = LineParser().formatSomethingElse(outputLine);
// Some more formatting, then do further processing with outputLine
If I run the sequence using callbacks, it is going to become an ugly set of nested callbacks really quickly when I have, say, 10 simple processing functions.
If I add methods chaining, the idea of prototype methods looks against functional style too, because functions in the chain will depend on previous state, not only on the input they get.
What should I do to make it look nicer in a functional style?
Update: After deeper research I found topic named Function Composition. It seems to be a proper solution to the problem and is one of the basic things from the functional world.
Here is the function I use to compose multiple functions into one:
var compose = function () {
var funcs = arguments;
return function () {
var args = arguments;
for (var i = funcs.length; i-- > 0;) {
args = [funcs[i].apply(this, args)];
}
return args[0];
};
};
Then I do a composition:
var composedFunction = compose(func1, func2, ..., funcn)
Which run from the right to left and all works just fine.
You lineparser seems to have methods like formatSpaces, capitalize and formatSomethingElse. The easiest thing you could do is to make all those methods to return this, so that you can chain those methods like so:
var outputline = LineParser.formatSpaces(inputLine).capitalize().formatSomethingElse()
Though by the looks of it, all of the methods require some string as a parameter, so you might have to make some implementation changes such as saving the string in a private variable if given and pullin it from the variable if no parameters are given.
Remark about your Edit. The function compose is very functional in the principle but not in its implementation. Indeed, the function mutates some variables (e.g., i and args) and is therefore not fully functional.
To avoid using these mutating variables, you could possibly define compose recursively. Another solution ould be to rely on third-party functional library, such as underscore-js for example (http://underscorejs.org/), which already defines a composition function.
Additional (obvious) remark: to make your code functional with compose, the functions func1, func2,... that are composed, should not mutate their arguments.
If you want asynchronous programming but you don't like nested callbacks, have you considered the async lib ?
You could have something like this :
var LineParser = require('../modules/LineParser');
var inputLine = 'A line with multiple spaces';
async.waterfall([
function(callback) {
var result = LineParser().formatSpaces(inputLine);
callback(null, result);
},
function(arg1, callback) {
var result = LineParser().capitalize(arg1);
callback(null, result);
},
function(arg1, callback) {
var result = LineParser().formatSomethingElse(arg1);
callback(null, result);
}
], function (err, result) {
// retrieve the final string
});
which can be turned into something useful if you modify your LineParser methods into asynchronous methods (otherwise it will only make your 3 lines heavier)
Functional style, that is, pure functional style that we see in Lisp etc. looks like this:
var outputline = formatSomethingElse(capitalize(formatSpaces(inputline)));
Often, for readability it would be formatted as:
var outputline = formatSomethingElse(
capitalize(
formatSpaces(inputline)
)
);
Any other form is not functional style. Functional style are a bit like Reverse Polish Notation in that the stated operation should be read in reverse. Indeed, RPN is itself a functional programming syntax (as embodied by Forth).
There is a style that has a similar look and feel to the functional style: method chaining:
var outputline = LineParser(inputline)
.formatSpaces()
.capitalize()
.formatSomethingElse()
.toString();
Unlike functional style, method chaining is read in order.
While the most famous chaining library, jQuery, mutates the state of the object it's not really necessary to do that. Take for example the following simple implementation of LineParser:
function LineParser (text) {
return {
text: text,
toString: function () {return this.text},
capitalize: function () {
// return a new object instead of "this"
return {
text : _capitalize(this.text),
toString : this.toString
}
}
}
}

What does _("id name") mean in javascript? [duplicate]

I came across the following javascript code:
this.removeEdge = function(source, target) {
if(!_states[source]) return;
var children = _states[source].children,
index = _(children).indexOf(target);
if(index !== -1) children.splice(index, 1);
};
What does _(children) mean?
_ is a valid variable identifier in JavaScript, and could theoretically refer to anything. Using _(...) with function syntax implies that _ is a function.
That said, it is commonly used by the underscore.js library, however if you're looking at minified code, it's quite possibly being used as another single-character variable name to save on file size.
In your example provided, it appears that underscore.js is being used to treat children as a collection, so that the indexOf function can be applied to the collection. This would be similar to calling:
_.indexOf(children, target);
Came looking for an answer to this and managed to find one. The _(variable) statement wraps underscore around the variable. According to this link in the "Object-Oriented and Functional Styles" section,
index = _(children).indexOf(target);
is equivalent to
index = _.indexOf(children, target);
The first is written in object-oriented style, which allows chaining of functions. Their example is as follows:
_(lyrics).chain()
.map(function(line) { return line.words.split(' '); })
.flatten()
.reduce({}, function(counts, word) {
counts[word] = (counts[word] || 0) + 1;
Each of these functions returns the underscore function wrapping lyrics, allowing chained manipulation of the lyrics variable.
Underscore changelog:
0.4.0 — November 7, 2009:
All Underscore functions can now be called in an object-oriented style, like so: _([1, 2, 3]).map(...);. Original patch provided by Marc-André Cournoyer. Wrapped objects can be chained through multiple method invocations. A functions method was added, providing a sorted list of all the functions in Underscore.
class Book {
constructor(author) {
this._author = author;
}
It is convention to precede the name of a private variable with an underscore (_). However, the practice itself does not make a variable private.

What does _(variable_name) mean in javascript?

I came across the following javascript code:
this.removeEdge = function(source, target) {
if(!_states[source]) return;
var children = _states[source].children,
index = _(children).indexOf(target);
if(index !== -1) children.splice(index, 1);
};
What does _(children) mean?
_ is a valid variable identifier in JavaScript, and could theoretically refer to anything. Using _(...) with function syntax implies that _ is a function.
That said, it is commonly used by the underscore.js library, however if you're looking at minified code, it's quite possibly being used as another single-character variable name to save on file size.
In your example provided, it appears that underscore.js is being used to treat children as a collection, so that the indexOf function can be applied to the collection. This would be similar to calling:
_.indexOf(children, target);
Came looking for an answer to this and managed to find one. The _(variable) statement wraps underscore around the variable. According to this link in the "Object-Oriented and Functional Styles" section,
index = _(children).indexOf(target);
is equivalent to
index = _.indexOf(children, target);
The first is written in object-oriented style, which allows chaining of functions. Their example is as follows:
_(lyrics).chain()
.map(function(line) { return line.words.split(' '); })
.flatten()
.reduce({}, function(counts, word) {
counts[word] = (counts[word] || 0) + 1;
Each of these functions returns the underscore function wrapping lyrics, allowing chained manipulation of the lyrics variable.
Underscore changelog:
0.4.0 — November 7, 2009:
All Underscore functions can now be called in an object-oriented style, like so: _([1, 2, 3]).map(...);. Original patch provided by Marc-André Cournoyer. Wrapped objects can be chained through multiple method invocations. A functions method was added, providing a sorted list of all the functions in Underscore.
class Book {
constructor(author) {
this._author = author;
}
It is convention to precede the name of a private variable with an underscore (_). However, the practice itself does not make a variable private.

JavaScript cache return value of a function with more than one parameter

I'm going through John Resig's snippets on advanced JavaScript. On #19 he mentions a method to cache the return value of a function. What's the best way to cache the return value of a function that has more than one parameter?
There has to be a much better way than stringify-ing the recieved arguments and using that as the key for the cache object:
function $$(selector, el) {
var cacheKey = JSON.stringify(arguments);
if ($$.cache[cacheKey]) return $$.cache[cacheKey];
return ($$.cache[cacheKey] = NodeListToArray( (el || document).querySelectorAll(s) ));
}
$$.cache = {};
You could use a custom hash function that can operate on objects. But hash functions cause collisions and would require significantly more code than your simple example.
Or you could make the cache n-dimensional, where n is the number of arguments. So essentially this:
function $$(selector, el) {
if ($$.cache[selector] && $$.cache[selector][el])
return $$.cache[cacheKey][el];
// etc.
That assumes that both selector and el are able to be used as object keys. You may need to stringify them in another manner.
Just consider an array element,
JSON (JavaScript Object Notation) works with generic platform, so for easy use you must create a function for your use,
Here, $$.cache[0] is your easy way after reading the cachekey,
If we make thing more easy, we might have security problem later.
I hope this will satisfy your requirement :)

Categories