Babelifying JavaScript Module Pattern with ES6 Arrow Functions [duplicate] - javascript

This question already has answers here:
ES6 immediately invoked arrow function
(4 answers)
Closed 4 years ago.
Babel is choking on code that uses the module pattern with an arrow function.
If I try to process a file which reads:
const lib = (() => {
function sum(a, b) { return a + b; }
function mult(a, b) { return a * b; }
return {
sum,
mult
};
}());
Babel gives a SyntaxError
{ SyntaxError: /home/david/Sync/ebs/office/fake.js: Unexpected token, expected "," (9:1)
7 | mult
8 | };
> 9 | }());
| ^
10 |
at Parser.raise (/home/david/Sync/ebs/office/node_modules/#babel/parser/lib/index.js:3939:15)
at Parser.unexpected (/home/david/Sync/ebs/office/node_modules/#babel/parser/lib/index.js:5248:16)
at Parser.expect (/home/david/Sync/ebs/office/node_modules/#babel/parser/lib/index.js:5236:28)
at Parser.parseParenAndDistinguishExpression (/home/david/Sync/ebs/office/node_modules/#babel/parser/lib/index.js:6454:14)
at Parser.parseExprAtom (/home/david/Sync/ebs/office/node_modules/#babel/parser/lib/index.js:6284:21)
at Parser.parseExprSubscripts (/home/david/Sync/ebs/office/node_modules/#babel/parser/lib/index.js:5924:21)
at Parser.parseMaybeUnary (/home/david/Sync/ebs/office/node_modules/#babel/parser/lib/index.js:5903:21)
at Parser.parseExprOps (/home/david/Sync/ebs/office/node_modules/#babel/parser/lib/index.js:5812:21)
at Parser.parseMaybeConditional (/home/david/Sync/ebs/office/node_modules/#babel/parser/lib/index.js:5784:21)
at Parser.parseMaybeAssign (/home/david/Sync/ebs/office/node_modules/#babel/parser/lib/index.js:5731:21)
pos: 137,
loc: Position { line: 9, column: 1 },
code: 'BABEL_PARSE_ERROR' }
However, if I change the code to use an older style function, like
const lib = (function () {
function sum(a, b) { return a + b; }
function mult(a, b) { return a * b; }
return {
sum,
mult
};
}());
Babel seems to process the file with no issues.
What am I doing wrong? Is there a genuine syntax problem with the arrow function code I am not aware of?

Try moving your paren inside, like this:
})();
const lib = (() => {
function sum(a, b) { return a + b; }
function mult(a, b) { return a * b; }
return {
sum,
mult
};
})();
console.log(lib)
In ES6, an arrow function basically consists of the following three components:
() => {}
So in order to invoke it immediately it should be wrapped in parentheses and then called, like this:
const lib = (() => {
//do something
})();

Due to the nature of arrow functions and how they are interpreted, (E.g. :
const x = () => ({ objectPropValues });
const x = () => { functionBody };
const x = () => conciseFunctionBody;
I imagine that the second arrow function in
const x = (() => {functionBody})();
const x = (() => {functionBody}());
Can not be allowed, and isn't.
This can probably be confirmed by looking carefully at the ECMA 6 specification for arrow functions.

Related

Passing arguments differently, function should still output the same value

Is there any way that I can write the function so that when I call it even by passing arguments differently, it still outputs the same value
I am new to JavaScript and was recently asked this question in an interview -
Write a function sum which when called like sum(2)(3) or sum(2, 3) should return 5.
This could be done individually as follows
function sum(a){
return function(b){
return a+b
}
}
or
function sum(a, b){
return a+b
}
If I follow the first code, it won't execute sum(a, b) and of course the second code will not support sum(a)(b). Is there any way that I can merge the two code snippets so that it executes doesn't matter how I call it ?
You'll need to check how many arguments were passed. If two are passed, return the added values; otherwise, return a function that, when called, returns its argument plus the closure's argument:
const sum = (...args) => {
if (args.length === 2) {
return args[0] + args[1];
}
return arg => arg + args[0];
};
console.log(sum(2)(3));
console.log(sum(2, 3));
More generally, you can create a makeSum function to handle when the total number of arguments to accept is an arbitrary number:
const makeSum = totalArgCount => {
const fn = (...args) => {
if (args.length === totalArgCount) {
return args.reduce((a, b) => a + b, 0);
}
return fn.bind(undefined, ...args);
};
return fn;
};
const sum2 = makeSum(2);
console.log(sum2(2)(3));
console.log(sum2(2, 3));
const sum4 = makeSum(4);
console.log(sum4(2)(3)(4)(5));
console.log(sum4(2, 3, 4)(5));
function sum(a, b) {
return b !== undefined ? (a + b) : function(b) { return a + b; }
}
console.log(sum(1,2));
console.log(sum(1)(3));
You can do it like this, by checking the b argument. If it is undefined, then you return a function. If it is not, you return the sum of the numbers.
Of course you could also check the both arguments are numbers, but this is simple version to illustrate what you want.

Problems In JavaScript Arrow Function [duplicate]

This question already has answers here:
What do multiple arrow functions mean in JavaScript?
(7 answers)
When should I use a return statement in ES6 arrow functions
(6 answers)
Closed 3 years ago.
I'm a newbie
I've download some source in this link
https://github.com/the-road-to-learn-react/react-redux-example
i have some proplem
in file src/app.js line 4
const applyFilter = searchTerm => article =>
article.title.toLowerCase().includes(searchTerm.toLowerCase());
why this can't work with
const applyFilter = searchTerm => article =>{
article.title.toLowerCase().includes(searchTerm.toLowerCase());
}
or
const applyFilter = searchTerm => {article =>
article.title.toLowerCase().includes(searchTerm.toLowerCase());
}
and in line 14 when call the funtion
articles.filter(applyFilter(searchTerm))
const applyFilter = searchTerm => article =>
article.title.toLowerCase().includes(searchTerm.toLowerCase());
this in my mind is call an arrow function inside an arrow function?
How can they put var 'article' in??
Arrow function syntax is kinda like this
(a) => b(a);
is equivalent to
function(a) {
return b(a);
}
However, when you add {} to an arrow function, it changes the meaning:
(a) => { b(a); }
is equivalent to
function(a) {
b(a);
// notice that this doesn't actually return anything,
// it just calls a function and does nothing with the result
}
So you have to add a return statement when you add brackets
(a) => { return b(a); }

Why do curly braces and/or whitespace make a difference? [duplicate]

This question already has answers here:
When should I use a return statement in ES6 arrow functions
(6 answers)
Closed 4 years ago.
Why is this-
const squareList = (arr) => {
"use strict";
const sqr = arr.filter((numbers) => {
numbers > 0 && Number.isInteger(numbers)
}).map((numbers) => {
Math.pow(numbers, 2)
})
return sqr;
};
functionally different to this-
const squareddList = (arr) => {
"use strict";
const sqr = arr.filter((numbers) => numbers > 0 && Number.isInteger(numbers)).map((numbers) => Math.pow(numbers, 2))
return sqr;
}
when the only difference between them is whitespace and curly braces?
When you pass an arbitrary array to both functions, the first returns an empty array and the second returns an array which has been filtered to only include positive integers and then squared.
Arrow functions without curly braces implicitly return the result of the expression in the function body so:
const someFunction = () => 10
someFunction(); // Returns 10
is equivalent to
const someFunction = () => {
return 10;
}
someFunction(); // Returns 10
and is NOT equivalent to:
const someFunction = () => {
10;
}
someFunction(); // Returns undefined
The difference is because in the first one you don't return the values.
In arrow function, if you put curly brackets you need to return the value, if not the values are returned.
const squareList = (arr) => {
"use strict";
const sqr = arr.filter((numbers) => {
return numbers > 0 && Number.isInteger(numbers)
}).map((numbers) => {
return Math.pow(numbers, 2)
})
return sqr;
};
This will work.

Jest doesn`t mock(set spy) on needed function

My test function reverseAdd call another function add that is defined in same module.
I need to test, if test function call another.
Module
function add(a, b) {
return a + b;
}
function reverseAdd(a, b) {
add(b, a);
}
module.exports = {
add,
reverseAdd
}
Test
const exp = require('./add');
describe('add', () => {
it('should add two numbers', () => {
expect(exp.add(1, 2)).toBe(3);
});
it('should add two numbers', () => {
exp.add = jest.fn();
exp.reverseAdd();
expect(exp.add).toHaveBeenCalledTimes(1);
});
});
Result
Expected mock function to have been called one time, but it was called zero
As I understand wraped function is another function, and it is not called in test function.
How can I wrap/spy the function add?
playground: https://repl.it/repls/WoodenElectricInstances
Thanks #ltamajs, I found solution.
Need to rewrite module to
function add(a, b) {
return a + b;
}
function reverseAdd(a, b) {
module.exports.add(b, a); <----- here changes
}
module.exports = {
add,
reverseAdd
}

What is the correct arrow function syntax?

Arrow functions can be written in a lot of different ways, are there any way that is "more correct"?
let fun1 = (a) => { return a; }
let fun2 = a => a;
Just like those cases above, is fun2 faster then fun1? What's the diference between them?
Arrow functions can be written in some diferent ways, like below:
// No params, just returns a string
const noParamsOnlyRet = () => 'lul';
// No params, no return
const noParamsNoRet = () => { console.log('lul'); };
// One param, it retuns what recives
const oneParamOnlyRet = a => a;
// Makes the same thing that the one above
const oneParamOnlyRet2 = a => { return a; };
// Makes the same thing that the one above
const oneParamOnlyRet3 = (a) => a;
/* Makes the same thing that the one above, parentheses in return are optional,
* only needed if the return have more then one line, highly recomended put
* objects into parentheses.
*/
const oneParamOnlyRet4 = (a) => (a);
// Mult params, it returns the sum
const multParamsOnlyRet = (a, b) => a + b;
// Makes the same thing that the one above
const multParamsOnlyRet2 = (a, b) => { return a + b; }
// Curly brackets are needed in multiple line arrow functions
const multParamsMultLines = (a, b) => {
let c = a + b;
return c;
}
So we have some rules:
Parentheses around the params are needed when the function has none or more than one param, if it have just one, parentheses can be omitted.
If the function just have a return the curly brackets and the keyword return can be omitted, if it fits in one line
Curly brackets are needed if the function have more than one line or if it have no return.
As you can see, all of this are valid syntax for arrow functions, none of them is faster than the other, which one you use depends of the way that you code.
From
function(a){return a}
remove function and add => between the () and the {}:
(a) => {return a}
If you only have one argument, you can remove the brackets:
a => {return a}
if everything in the {} is a return statement, you can remove the {return ...} and leave just the statement:
a => a

Categories

Resources