Please explain usage of _.identity(value) of underscore.js - javascript

Please explain usage of _.identity(value) of underscore.js. Not able to understand it from the documentation ( http://underscorejs.org/#identity ).
Can you provide some example of its usage?

A JavaScript code pattern involving identity is filtering values based on truthiness, e.g.
var a = [null, null, [1,2,3], null, [10, 12], null];
a.filter(_.identity)
yields [Array[3], Array[2]].
Using
_.compact(a)
is clearer, but one may not use lodash or underscore at all, e.g.
function identity(x) {
return x;
}
a.filter(identity)
Whether it is a good code pattern is questionable for several reasons, but it's being used in the wild.
It is not a NOOP at all. A NOOP is an imperative construct in e.g. assembly, whereas in functional programming, it is like other functions in that it returns a value. If identity were a NOOP, then all pure functions could also be considered noop, and it would not be a sensible thing.

It's essentially a no-operation function. It returns the value of whatever was passed into it.
The part about it being used as a "default iterator" within the library itself means that in other functions which may have an optional "iterator" parameter (which is likely used as a function to apply to each element of an array of some kind), if no iterator parameter is passed, the library will use this "no-op" iterator instead and the elements of the array will remain unchanged.

A specific example:
Underscore.js defines _.each and as like this.
_.each = function(obj, iterator, context) {
...
}
This iterator shows el value. You maybe have used this idiom.
_.each([1, 2, 3], function(el){
console.log(el);
});
This iterator returns el value without change.
_.each([1, 2, 3], function(el){
return el;
});
The function that returns a value without change occur frequently. So Underscore.js wants to define the function. Underscore.js names the function _.identity.
_.identity = function(value) {
return value;
};
If Underscore.js wants to use a default iterator, all Underscore.js need is call _.identity.
_.each([1, 2, 3], _.identity);

Related

How to use a function inside a javascript Map Object

Am trying to understand Maps objects in javascript, and how to use them inside an application, but there's something that i cant understand and it leads me to this question, here's my example
const myMap = new Map();
myMap.set('Name', 'John Doe')
.set(1, function sayHello(user){ console.log(`Hello ${user}`)})
myMap.get('Name'); // output John Doe
myMap.get(1); // output [function: sayHello]
as you see above i can set a function inside the Map
how can i use that function?
what's the point of setting a function in a Map?
are there any use cases?
I'm so confused, i will appreciate any explanation
What you've stored in the map is a function object. To understand it better, take a look at the following snippet to observe the difference between sayHello and sayHello("World"). The former is the function object and the latter is an invocation.
const sayHello = (user) => console.log(`Hello ${user}`)
console.log(sayHello);
sayHello("World");
You'd observe that the .get returns you the function object. To see it in action, you need to invoke it with ().
myMap.get(1)("World");
Among other things, maps could help you organize function objects and have, arguably, more readable code. For comparison, check the following implementations.
function calculator(operation, a, b) {
if (operation === "add") {
return a + b;
} else if (operation === "subtract") {
return a - b;
} else if (operation === "multiply") {
return a * b;
}
}
console.log(calculator("add", 5, 10));
console.log(calculator("subtract", 5, 10));
console.log(calculator("multiply", 5, 10));
function calculator(operation, a, b) {
const operations = new Map([
["add", (a, b) => a + b],
["subtract", (a, b) => a - b],
["multiply", (a, b) => a * b],
]);
return operations.get(operation)(a, b);
}
console.log(calculator("add", 5, 10));
console.log(calculator("subtract", 5, 10));
console.log(calculator("multiply", 5, 10));
1. `myMap.get(1)(userName)
2. Several: Functions are objects that define behaviours. You can pass them as parameters as callbacks, transformation filters, etc... Storing them in a Map or just a regular object is just a matter of getting faster access when accessing by some key.
3. Lots of them. You can store not only functions in maps but even whole classes if you want even in most cases it would be more handy (and almost equally efficient) to just use a regular object.
The point is never finding use cases for a thing but having that thing in your toolbox in order to be able to use it as soon as the necessity arises. In this case, when you have a set of key-function pairs big enough.
HINT: If you are curios on more use cases, search for functional programming stuff.
You need to invoke the function by passing the argument like:
myMap.get(1)("user");
If you want to use the function inside the map ( like set above ) then use like this : myMap.get(1)('name')
Map accepts any key type
If the object's key is not a string or symbol, JavaScript implicitly transforms it into a string.
Contrary, the map accepts keys of any type: strings, numbers, boolean, symbols. Moreover, the map preserves the key type. That's the map's main benefit.
There are specific usecases where map win the race over objects :
Map can contain keys of any data type, it could be Objects, integers, strings, boolean, functions or arrays. But in Objects, the key must always be a string or a symbol.
A Map is ordered and iterable, whereas a objects is not ordered and not iterable
Checking the number of entries in a Map is quite easy compared to checking that of Objects.
A Map inherits from Map.prototype. This offers all sorts of utility functions and properties which makes working with Map objects a lot easier
There are chances of accidentally overwriting inherited properties from prototypes by writing JavaScript identifiers as key names of an object (e.g., toString, constructor, etc.) at that case, use Maps
Another object cannot be used as key of an object, so no extra information can be written for an object by writing that object as key of another object and value of that another object will contain the extra information but this is possible in the case of Maps
and much more...
Remember! : debugging with Maps is painful then the objects
I Hope this answer helps you!
Comment if you have any questions or doubts and don't forget to mark the answer as accepted if you find it useful because it'll be helpful for others who're looking the answer for the same question.
Have a great day!

Renaming built in javascript functions

Can one rename a built in JavaScript function?
I am trying to rename the "reverse" function to another name,
but still have it do the same function
You can change the name by creating an alias in the prototype for the function
Array.prototype.newreversename = Array.prototype.reverse;
var arr=["abc","sssd"];
console.log(arr.newreversename())
You can also create a wrapper function for the new function
Array.prototype.newreversefunction = function() {
return this.reverse();
};
var arr=["a","c"];
console.log(arr.newreversefunction())
You can, but don't
This is called monkey patching. Javascript is flexible enough to allow you to change fundamental things like this, but you will break other code and make your own code unreadable by others if you modify normal parts of the language this way.
That said, you can assign and clear things, even in prototypes like this
Array.prototype.rev = Array.prototype.reverse
> function reverse() { [native code] }
Array.prototype.reverse = null
> null
[1,2,3,4,5].rev()
> [5, 4, 3, 2, 1]
[1,2,3,4,5].reverse()
> "[1,2,3,4,5].reverse is not a function"
You can, but I would strongly recommend against doing so.
The proper way to do it would be to get the property descriptor for the method from the prototype (Object.getOwnPropertyDescriptor), then use that to define a new property (Object.defineProperty), and use delete to get rid of the previous one:
Object.defineProperty(
Array.prototype,
"thingy",
Object.getOwnPropertyDescriptor(Array.prototype, "reverse")
);
delete Array.prototype.reverse;
console.log([1,2,3].thingy()); // [3, 2, 1]
console.log([1,2,3].reverse()); // Error
You can do it like this:
Array.prototype.myReverse = Array.prototype.reverse;
delete Array.prototype.reverse;
But you should avoid this, as many libraries rely on the reverse function. Instead, if you want to call it using another name, just do the first line:
Array.prototype.myReverse = Array.prototype.reverse;
You can change the name by creating an alias
Array.prototype.slicing = Array.prototype.slice;
var animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];
console.log(animals.slicing(2))

javascript es6: use case for destructuring rest parameter

I just saw a code snippet in MDN about destructuring rest parameters like so:
function f(...[a, b, c]) {
return a + b + c;
}
f(1) // NaN (b and c are undefined)
f(1, 2, 3) // 6
f(1, 2, 3, 4) // 6 (the fourth parameter is not destructured)
the code snippet is in this page: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters
Although the common use case for rest parameters is very clear to me (function foo(...params){/*code*/}) I could not think about a real world use case to use rest parameters like the way presented in that code snippet. Instead, I think that in that case, I should just use a common function definition:
function f(a, b, c) {
return a + b + c;
}
f(1) // NaN (b and c are undefined)
f(1, 2, 3) // 6
f(1, 2, 3, 4) // 6 (the fourth parameter is not defined)
Your function f(a, b, c) { … } is indeed the proper way to write this. The only difference between that and the rest+destructuring syntax is that rest parameters do not add to number of parameters, i.e. f.length == 0.
There really is no good use case for putting an array destructuring pattern as the target of a rest parameter. Just because the syntax allows it doesn't mean that it's useful somewhere. The MDN example probably should've made that more clear.
The example illustrates that rest and destructuring syntaxes are flexible enough to be combined even in such a way.
It is known that neither TypeScript nor Babel stable versions currently support this syntax, primarily because it's of no practical use.
let's say that we have a function that returns an object such like that:
function getCustomer(id) {
return fetch(`http://myapi.com/customer/${id}`);
}
and let's say I have a response like that:
{
"customer": {
"id": 1234,
"name": "John Doe",
"latestBadges": [
"Platinum Customer",
"100 Buys",
"Reviewer"
]
}
}
In a more traditional approach I could write a function to show the latest 3 badges like so:
function showLatestBadges(a, b, c) {
console.log(a, b, c);
}
and to use that function, I would need to to:
getCustomer(1234).then((customer) => {
showLatestBadges(
customer.latestBadges[0],
customer.latestBadges[1],
customer.latestBadges[2]
);
});
With this new spread operator, I could do this instead:
getCustomer(1234).then((customer) => {
showLatestBadges(...customer.latestBadges);
});
So, using the spread operator in the function definition may look like it's a little useless. But, in fact, it CAN be useful in a VERY specific situation:
Let's say we have a legacy system, and let's say that the call to the showLatestBadges function is being made in hundreds of places without using the spread operator, just like the old days. Let's also assume that we are using a linting tool that prevents unused variables, and let's also assume that we are running a build process that do cares about the linting results, and if the linting says that something is not right, the build fails.
Let's ALSO ASSUME that for some weird business rule, we now have to show only the first and third badges.
Now, assuming this function call being made in hundreds of places in the legacy system, and we do not have much time available to deliver the implementation of this new business rule, we do not have time to refactor the code for ALL those hundreds of calls.
So, we will now change the function as so:
function showLatestBadges(a, b, c) {
console.log(a, c);
}
But now we have a problem: the build fails because of the unused b variable, and we have to deliver this change for YESTERDAY!!! We have no time to refactor all the hundreds of calls to this function, and we cannot just do a simple find and replace in all the spots, because we have such a messy code, and there are evals all over the place, and unpredictable behavior can happen.
So, one solution is: change the function signature using the spread operator, so the build succeeds, and create a task on the board to do the refactoring.
So, we can change the function as so:
function showLatestBadges(...[a,,c]) {
console.log(a, c);
}
Ok, I know this is a VERY specific situation and that this is very unlike to happen, but, who knows? ¯\_(ツ)_/¯
Actually the ... operator is two ways. It's both called rest and spread depending on your use case. They are both very powerful operators especially for functional approaches. You may always use spread operator as,
var a = [1,2,3],
b = [4,5,6];
a.push(...b);
which would yield a to be [1,2,3,4,5,6] all at once. At this moment one could say that .concat() could do the same. Yes concat has a built in spread functionality but a.concat(b) wouldn't effect a. I just creates and returns a new array. In fact in proper functional languages treating a as an immutable object is nice for the sake of purity. Yet JS is a weird language. It's believed to be functional but at the same time deeply embraces reference types. So long story short if you want to keep the references to a intact while mutating it then you can not use a.concat(b) but a.push(...b). Here i have to mention that .push() is not perfectly designed because it returns a stupid length property which is totally useless. It should have returned a. So I end up using the comma operator like (a.push(...b),a) most of the times.
OK apart from simple use cases you may stretch ... further for a little more complicated but cool looking implementations. Such as you may do an Haskellesque pattern matching to split head and tail of an array and recurse accordingly.
Here is a useful case of spread and rest operators working hand to hand to flatten an arbitrary nested array.
var flat = (x,...xs) => x ? [...Array.isArray(x) ? flat(...x) : [x], ...flat(...xs)] : [];
var na = [[1,2],[3,[4,5]],[6,7,[[[8],9]]],10];
fa = flat(na);
console.log(fa);
This is one of the use-cases I got to use this
const tail = function([, ...xs]) {
return xs;
}
tail([1,2]); // [2]
const head = ([a]) => a
head([1,2,3,4]) // 1

How to call a function by an array of argument values? [duplicate]

I've tried the following with no success:
function a(args){
b(arguments);
}
function b(args){
// arguments are lost?
}
a(1,2,3);
In function a, I can use the arguments keyword to access an array of arguments, in function b these are lost. Is there a way of passing arguments to another javascript function like I try to do?
Use .apply() to have the same access to arguments in function b, like this:
function a(){
b.apply(null, arguments);
}
function b(){
console.log(arguments); //arguments[0] = 1, etc
}
a(1,2,3);
You can test it out here.
Spread operator
The spread operator allows an expression to be expanded in places where multiple arguments (for function calls) or multiple elements (for array literals) are expected.
ECMAScript ES6 added a new operator that lets you do this in a more practical way: ...Spread Operator.
Example without using the apply method:
function a(...args){
b(...args);
b(6, ...args, 8) // You can even add more elements
}
function b(){
console.log(arguments)
}
a(1, 2, 3)
Note This snippet returns a syntax error if your browser still uses ES5.
Editor's note: Since the snippet uses console.log(), you must open your browser's JS console to see the result - there will be no in-page result.
It will display this result:
In short, the spread operator can be used for different purposes if you're using arrays, so it can also be used for function arguments, you can see a similar example explained in the official docs: Rest parameters
The explanation that none of the other answers supplies is that the original arguments are still available, but not in the original position in the arguments object.
The arguments object contains one element for each actual parameter provided to the function. When you call a you supply three arguments: the numbers 1, 2, and, 3. So, arguments contains [1, 2, 3].
function a(args){
console.log(arguments) // [1, 2, 3]
b(arguments);
}
When you call b, however, you pass exactly one argument: a's arguments object. So arguments contains [[1, 2, 3]] (i.e. one element, which is a's arguments object, which has properties containing the original arguments to a).
function b(args){
// arguments are lost?
console.log(arguments) // [[1, 2, 3]]
}
a(1,2,3);
As #Nick demonstrated, you can use apply to provide a set arguments object in the call.
The following achieves the same result:
function a(args){
b(arguments[0], arguments[1], arguments[2]); // three arguments
}
But apply is the correct solution in the general case.
If you want to only pass certain arguments, you can do so like this:
Foo.bar(TheClass, 'theMethod', 'arg1', 'arg2')
Foo.js
bar (obj, method, ...args) {
obj[method](...args)
}
obj and method are used by the bar() method, while the rest of args are passed to the actual call.
This one works like a charm.
function a(){
b(...arguments);
}
function b(){
for(var i=0;i<arguments.length;i++){
//you can use arguments[i] here.
}
}
a(1,2,3);

JavaScript variable number of arguments to function

Is there a way to allow "unlimited" vars for a function in JavaScript?
Example:
load(var1, var2, var3, var4, var5, etc...)
load(var1)
Sure, just use the arguments object.
function foo() {
for (var i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
}
In (most) recent browsers, you can accept variable number of arguments with this syntax:
function my_log(...args) {
// args is an Array
console.log(args);
// You can pass this array as parameters to another function
console.log(...args);
}
Here's a small example:
function foo(x, ...args) {
console.log(x, args, ...args, arguments);
}
foo('a', 'b', 'c', z='d')
=>
a
Array(3) [ "b", "c", "d" ]
b c d
Arguments
​ 0: "a"
​1: "b"
​2: "c"
​3: "d"
​length: 4
Documentation and more examples here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters
Another option is to pass in your arguments in a context object.
function load(context)
{
// do whatever with context.name, context.address, etc
}
and use it like this
load({name:'Ken',address:'secret',unused:true})
This has the advantage that you can add as many named arguments as you want, and the function can use them (or not) as it sees fit.
I agree with Ken's answer as being the most dynamic and I like to take it a step further. If it's a function that you call multiple times with different arguments - I use Ken's design but then add default values:
function load(context) {
var defaults = {
parameter1: defaultValue1,
parameter2: defaultValue2,
...
};
var context = extend(defaults, context);
// do stuff
}
This way, if you have many parameters but don't necessarily need to set them with each call to the function, you can simply specify the non-defaults. For the extend method, you can use jQuery's extend method ($.extend()), craft your own or use the following:
function extend() {
for (var i = 1; i < arguments.length; i++)
for (var key in arguments[i])
if (arguments[i].hasOwnProperty(key))
arguments[0][key] = arguments[i][key];
return arguments[0];
}
This will merge the context object with the defaults and fill in any undefined values in your object with the defaults.
It is preferable to use rest parameter syntax as Ramast pointed out.
function (a, b, ...args) {}
I just want to add some nice property of the ...args argument
It is an array, and not an object like arguments. This allows you to apply functions like map or sort directly.
It does not include all parameters but only the one passed from it on. E.g. function (a, b, ...args) in this case args contains
argument 3 to arguments.length
Yes, just like this :
function load()
{
var var0 = arguments[0];
var var1 = arguments[1];
}
load(1,2);
As mentioned already, you can use the arguments object to retrieve a variable number of function parameters.
If you want to call another function with the same arguments, use apply. You can even add or remove arguments by converting arguments to an array. For example, this function inserts some text before logging to console:
log() {
let args = Array.prototype.slice.call(arguments);
args = ['MyObjectName', this.id_].concat(args);
console.log.apply(console, args);
}
Although I generally agree that the named arguments approach is useful and flexible (unless you care about the order, in which case arguments is easiest), I do have concerns about the cost of the mbeasley approach (using defaults and extends). This is an extreme amount of cost to take for pulling default values. First, the defaults are defined inside the function, so they are repopulated on every call. Second, you can easily read out the named values and set the defaults at the same time using ||. There is no need to create and merge yet another new object to get this information.
function load(context) {
var parameter1 = context.parameter1 || defaultValue1,
parameter2 = context.parameter2 || defaultValue2;
// do stuff
}
This is roughly the same amount of code (maybe slightly more), but should be a fraction of the runtime cost.
While #roufamatic did show use of the arguments keyword and #Ken showed a great example of an object for usage I feel neither truly addressed what is going on in this instance and may confuse future readers or instill a bad practice as not explicitly stating a function/method is intended to take a variable amount of arguments/parameters.
function varyArg () {
return arguments[0] + arguments[1];
}
When another developer is looking through your code is it very easy to assume this function does not take parameters. Especially if that developer is not privy to the arguments keyword. Because of this it is a good idea to follow a style guideline and be consistent. I will be using Google's for all examples.
Let's explicitly state the same function has variable parameters:
function varyArg (var_args) {
return arguments[0] + arguments[1];
}
Object parameter VS var_args
There may be times when an object is needed as it is the only approved and considered best practice method of an data map. Associative arrays are frowned upon and discouraged.
SIDENOTE: The arguments keyword actually returns back an object using numbers as the key. The prototypal inheritance is also the object family. See end of answer for proper array usage in JS
In this case we can explicitly state this also. Note: this naming convention is not provided by Google but is an example of explicit declaration of a param's type. This is important if you are looking to create a more strict typed pattern in your code.
function varyArg (args_obj) {
return args_obj.name+" "+args_obj.weight;
}
varyArg({name: "Brian", weight: 150});
Which one to choose?
This depends on your function's and program's needs. If for instance you are simply looking to return a value base on an iterative process across all arguments passed then most certainly stick with the arguments keyword. If you need definition to your arguments and mapping of the data then the object method is the way to go. Let's look at two examples and then we're done!
Arguments usage
function sumOfAll (var_args) {
return arguments.reduce(function(a, b) {
return a + b;
}, 0);
}
sumOfAll(1,2,3); // returns 6
Object usage
function myObjArgs(args_obj) {
// MAKE SURE ARGUMENT IS AN OBJECT OR ELSE RETURN
if (typeof args_obj !== "object") {
return "Arguments passed must be in object form!";
}
return "Hello "+args_obj.name+" I see you're "+args_obj.age+" years old.";
}
myObjArgs({name: "Brian", age: 31}); // returns 'Hello Brian I see you're 31 years old
Accessing an array instead of an object ("...args" The rest parameter)
As mentioned up top of the answer the arguments keyword actually returns an object. Because of this any method you want to use for an array will have to be called. An example of this:
Array.prototype.map.call(arguments, function (val, idx, arr) {});
To avoid this use the rest parameter:
function varyArgArr (...var_args) {
return var_args.sort();
}
varyArgArr(5,1,3); // returns 1, 3, 5
Use the arguments object when inside the function to have access to all arguments passed in.
Be aware that passing an Object with named properties as Ken suggested adds the cost of allocating and releasing the temporary object to every call. Passing normal arguments by value or reference will generally be the most efficient. For many applications though the performance is not critical but for some it can be.
Use array and then you can use how many parameters you need. For example, calculate the average of the number elements of an array:
function fncAverage(sample) {
var lenghtSample = sample.length;
var elementsSum = 0;
for (var i = 0; i < lenghtSample; i++) {
elementsSum = Number(elementsSum) + Number(sample[i]);
}
average = elementsSum / lenghtSample
return (average);
}
console.log(fncAverage([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])); // results 5.5
let mySample = [10, 20, 30, 40];
console.log(fncAverage(mySample)); // results 25
//try your own arrays of numbers

Categories

Resources