I've put together a simplified example of what I'm trying to do, obviously a bit contrived... I have this class:
export class myClass {
a = 'bar';
b = 0;
save(x: any = null): void {
//save all properties
//...
}
}
In other classes that need to use it, I will define foo = new myClass();
Then it can be used either as:
this.foo.b = 3
this.foo.save();
or, because sometimes I just want it on one line (hence the x: any = null:
this.foo.save(this.foo.b = 3);
I would like to write the single line version more elegantly, and feel something like this should be possible... is it?
//How can I make this possible?
this.foo.save(c => c.b = 3)
if it is possible, what would the add method look like?
Many thanks!
Answer for the original question.
If you want this.calc.add(c => c.b = 3), then you need to handle invoking the function c => c.b = 3 once passed to the add method.
So just check the value is a function, if it is then pass this to the function, which would be c in your function, then the return value you add with this.b
Plain old js.
class Calculator {
constructor() {
this.a = 10
this.b = 0
this.sum = 0
}
add(x) {
this.sum = this.a + (typeof x === 'function' ? x(this) : x)
}
}
const calc = new Calculator()
calc.add(c => c.b = 3)
console.log(calc.sum)
calc.add(1)
console.log(calc.sum)
Implicitly assigning is anti pattern
// Something that you should avoid
this.calc.b = 3
class Calc {
constructor(private a: number = 0, private b: number = 0) {}
setA(a: number) {
this.a = a;
return this;
}
setB(b: number) {
this.b = b;
return this;
}
sum() {
return this.a + this.b;
}
}
const calc = new Calc();
// will return 0
console.log(calc.sum());
// will return 6
console.log(calc.setA(1).setB(5).sum());
const calc1 = new Calc(1,2);
// will return 3
console.log(calc1.sum());
This question already has answers here:
ECMAScript 6 arrow function that returns an object
(6 answers)
Closed 3 years ago.
I've seen this type of JavaScript code (contrived):
const a = "hello"
const b = () => ({a})
Is this just shorthand for this equivalent fat arrow function:
const b = () => { return {a} }
Or does it have some other purpose? And what do you call these?
It seems a lot to add a construct just to save one reserved word.
I think you are asking about the right side of an arrow function.
It is just more concise, with the special rule that if the right side is a single expression to be returned, it doesn't have to be { return expr }, but just expr.
const sq = (x => x * x);
const hyphenAround = (s => `-${s}-`);
[1, 3, 5].map(a => a * a)
[1, 3, 5].reduce((a, b) => a + b)
const sq = (x => x * x);
const hyphenAround = (s => `-${s}-`);
console.log(sq(3));
console.log(hyphenAround("hello"));
console.log([1, 3, 5].map(a => a * a));
console.log([1, 3, 5].reduce((a, b) => a + b));
In your example, it is
const a = "hello"
const b = () => ({a})
which is the same as
const a = "hello"
const b = () => ({a: a})
Those are called shorthand property names.
let a = "hello"
const b = () => ({
a
});
console.log(b());
a = "a long sentence";
console.log(b());
x = 123;
y = "hello"
z = [1, 3, 5];
console.log({
x,
y,
z
});
While going through features of JavaScript, I used default arguments and spread syntax in same function.
let whatIsThis = (a, b = 2, ...c) => {
console.log("a = " + a, "b = " + b,"c = " + c)
}
whatIsThis(a = 1, c = [2,3,4,5,6,7,8])
After running it, I expected output to be like this:
"a = 1"
"b = 2"
"c = 2,3,4,5,6,7,8"
But instead I got this:
"a = 1"
"b = 2,3,4,5,6,7,8"
"c = "
Why didn't this worked?
It's because you can't pass named arguments to a function in JavaScript. When you do whatIsThis(a = 1, c = [2,3,4,5,6,7,8]) what it really means is whatIsThis(1, [2,3,4,5,6,7,8]) (because a = 1 statement returns 1).
What you can do is move default argument to the end (which is generally a good practice) or wrap your arguments in objects. For example
let whatIsThis = ({a, b = 2, c}) => {
console.log("a = " + a, "b = " + b,"c = " + c)
}
whatIsThis({a: 1, c: [2,3,4,5,6,7,8]})
You could use undefined for the second parameter and use spread syntax ... for all other parameters of the function who are collected with rest parameters ....
JavaScript does not have named parameters.
You need to hand over the parameters in the same order as the function signature.
let whatIsThis = (a, b = 2, ...c) => {
console.log("a = " + a, "b = " + b, "c = " + c)
}
whatIsThis(1, undefined, ...[2, 3, 4, 5, 6, 7, 8])
// ^^^^^^^^^ takes default value
// ^^^^^^^^^^^^^^^^^^^^^^^^ spreads values for rest parameters
You need to call as whatIsThis(a = 1, undefined , c = [2,3,4,5,6,7,8]) because you are using a default parameter in the middle of the function parameter so that should be called as undefined to use the default value.
let whatIsThis = (a, b = 2, ...c) => {
console.log("a = " + a, "b = " + b,"c = " + c)
}
whatIsThis(a = 1, undefined , c = [2,3,4,5,6,7,8])
Javascript does not have named arguments. Arguments are assigned to parameters based only by position. You cannot assign arguments by name and you cannot simply skip the b argument. This:
whatIsThis(a = 1, c = [2,3,4,5,6,7,8])
Is equivalent to:
a = 1;
c = [2,3,4,5,6,7,8];
whatIsThis(a, c);
a = 1 here is an assignment operation creating a new global variable; it has nothing to do with the parameter a of the function.
The order of the function parameter matters. In this case the the function order is (a, b = 2, ...c) but the function is called with only two parameters whatIsThis(a = 1, c = [2,3,4,5,6,7,8]).
So basically the argument c is undefined when the function is called and the parameter b refers to the array [2,3,4,5,6,7,8].
Also note calling a function like this whatIsThis(a = 1, c = [2,3,4,5,6,7,8]) will led some linting tools and IDE to throw error.
function partialize(){
}
function calculation(a,b,c){
console.log(a*b/c);
return a*b/c;
}
var a = 10, b= 20, c= 5;
var partialize1 = partialize(calculation, a);
partialize1(b,c)
var partialize2 = partialize(calculation, a, b);
partialize2(c)
var partialize3 = partialize(calculation, a, b, c);
partialize3()
I need to write partialize function which give same output in all three condition.
I tried like that it work .but i used spread operator .can we do this without spread operator ?
function partialize(fn,...a) {
console.log(...a);
return function (...b) {
console.log(...b);
fn(...a,...b);
}
}
function calculation(a, b, c) {
console.log(a * b / c);
return a * b / c;
}
var a = 10, b = 20, c = 5;
var partialize1 = partialize(calculation, a);
partialize1(b, c)
var partialize2 = partialize(calculation, a, b);
partialize2(c)
var partialize3 = partialize(calculation, a, b, c);
partialize3()
can we do the same thing without spread operator ?
You can save the initial arguments that were passed and return a function that can be called with the rest of the arguments, then calling the original function with apply:
function partialize(fn) {
const initialArguments = Array.from(arguments).slice(1);
return function() {
const finalArguments = Array.from(arguments);
fn.apply(null, initialArguments.concat(finalArguments));
}
}
function calculation(a, b, c) {
console.log(a * b / c);
return a * b / c;
}
var a = 10,
b = 20,
c = 5;
var partialize1 = partialize(calculation, a);
partialize1(b, c)
var partialize2 = partialize(calculation, a, b);
partialize2(c)
var partialize3 = partialize(calculation, a, b, c);
partialize3()
If your code is currently working as is but you'd like to change it to not use the spread operator, you can use the arguments object instead.
arguments object:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments
Also check out this stackoverflow question for some example code working with the arguments object if helpful. How can I convert the "arguments" object to an array in JavaScript?
user944513, to simulate an overload of methods in javascript, yo can use the arguments object, which comes by default in the functions. To explain you better, i've written a block of code. Hope this can help you:
function suma(a = 0){
let resultado = 0;
console.log(arguments.length);
for(let i = 0; i < arguments.length; i++)
{
if(typeof(arguments[i] == "number")){
resultado += arguments[i];
}
}
}
suma(1,2,3,4); // 10
suma(1,2) // 3
In many functions I have noticed the following pattern: function declares variables, combines it to the result and returns result. It is shown in this very simple example:
function fn() {
var a = 1,
b = 2;
return a + b;
}
fn(); // 3
or:
function fn() {
var a, b;
return a = 1,
b = 2,
a + b;
}
fn(); // 3
I would like to minimize this code and reduce it to the one statement. It could look like this:
function fn() {
return a = 1,
b = 2,
a + b;
}
However this code declares variables a, b in global scope which is not acceptable. Is it possible to do this in javascript?
Maybe this works for you, which is not advisable because of using assignment alogn with the comma operator.
function fn(a, b) { // declaration in local scope
return a = 1, b = 2, a + b; // return value with comma operator
}
A newer approach takes default values and returns just the addition of both.
fn = (a = 1, b = 2) => a + b;
What you are trying to do (declare using var and return in same statement) is not possible with JavaScript syntax.
The most concise you can get is your first option:
function fn() {
var a = 1,
b = 2;
return a + b;
}
fn(); // 3