Optimize custom Object Property in Array with Javascript - javascript

Look at the 3 lines of code within this Javascript function. Assume that y will always be a String:
function example(x, y) {
var s = {};
s[y] = x;
return s;
}
Bearing in mind the following:
Without wrapping it further within a function
Without using ;
Is it possible to condense the 3 lines of code into one?

Yes, with a little ugly code:
function example(x, y, s) {
return (s = {})[y] = x, s;
}
The extra parameter s is not passed into the function, it's only there to be declared as a variable, so you don't need the extra line var s;. (If you don't declare it locally it becomes a global variable, which is bad practice.)
The value of the assignment s = {} is what's assigned, so you can make the assignment and then continue using the value in the expression.
The comma operator returns the last value, e.g. (1,2) returns the value 2. That way you can add , s to the expression to make it return s.
Edit:
Another variation is using s as a variable in a for loop, and exit out of the loop:
function example(x, y) {
for(var s = {}; s[y] = x, true;) return s;
}

Is using function cheating? :)
function example(x, y) {
return new function () { this[y] = x; };
}

There is always evil eval:
function example(x, y) {
return eval('({' + y + ':"' + x + '"})');
}
But I still don't see the point in this.

Related

javascript inline function - what are the results?

What does this function return? I'm not familiar with this nomenclature.
let x = 2;
let y = 8;
const a = function(b) { return function(c) { return x + y + Math.abs(b) + c; } };
// Statement will go here
const fn = a(x);
For the above function, I understand the x+y part, but what is the b and c referred to in the second half? Is a(x) calling const a?
The only thing I found that refers to similar nomenclature is function x y a b in javascript, but the discussion doesn't talk about how to find what is returned. Maybe I'm not searching for the right thing and that's why my search only returned one thing that is similar.
a is the result of a function that accepts an argument, b. That function returns another function that accepts an argument c and returns x + y + c plus absolute value of b.
let x = 2;
let y = 8;
const a = function(b) {
console.log({
b
});
return function(c) {
console.log({
c
});
return x + y + Math.abs(b) + c;
}
};
// Statement will go here
const fn = a(x);
fn(12) // will have b=2 and c=12
It seems like a function pointer. function(b) accepts the parameter x that was passed into the function pointer a, this function pointer references function(b) but unlike normal functions which immediately returns a value, function(b) returns another function function(c) which ofcourse accepts one parameter and that parameter should be filled out when const fn was invoked.
My theory is that when you call fn for example fn(3) then you will get a result equivalent to 2 + 8 + Math.abs(2) + 3;
Without const fn you could also invoke a like a(2)(3) which I believe will yeild the same result.
Hope this helps.
What you see here is called currying, something related, but different from partial application.
The point is to break down a function call taking multiple arguments into multiple function calls taking single arguments.
In this case, a is a function that returns a function that returns the result of adding x, y, the absolute of b (coming from the call to a) and c (coming from the call to the return value of a).

How does JavaScript pass values to a function expression within a declaration?

I'm working through Head First JavaScript and have an example:
function addN(n) {
var adder = function(x) {
return n + x;
};
return adder;
}
var add2 = addN(2);
console.log(add2(10));
console.log(add2(100));
addN(2) gets assigned to add2, but nothing gets assigned to the x. However, upon running the code, the arguments 10 and 100 clearly get passed to the x. How does JavaScript know to pass the 10 and 100 to the x value?
When you do this:
var add2 = addN(2);
The variable add2 is now effectively this:
function(x) {
return 2 + x;
}
Because that function itself is the return value of addN(). (Note that in JavaScript a function is a value that can be assigned to a variable like any other value.)
So when you further do this:
add2(10);
You are passing 10 to that function, so x will be 10.

Unfamiliar use of square brackets in calling a function

In the middle of this page, I find the code below.
var plus = function(x,y){ return x + y };
var minus = function(x,y){ return x - y };
var operations = {
'+': plus,
'-': minus
};
var calculate = function(x, y, operation){
return operations[operation](x, y);
}
calculate(38, 4, '+');
calculate(47, 3, '-');
Now while I can trace how it works, I've never seen this use of square brackets before. It certainly doesn't look like it's creating an array or referencing a member of an array. Is this common? If so, where are some other examples?
It is a dictionary access, which is like an array, but with a key instead of a numeric index.
operations['+'] will evaluate to the function plus, which is then called with the arguments plus(x,y).
It's called bracket notation.
In JavaScript you can use it to access object properties.
here operations is an object where the symbols + and - refers to two functions.
operations[operation] will return a reference to function plus where value of operation is + and then the following () will invoke the function
operations is an object and when you do operations[property] you will get the associated function and then you are passing the operands as x and y.
operations['+'] is function (x,y){ return x + y } which is plus
operations['-'] is function (x,y){ return x - y } which is minus
My JavaScript book says that object properties need be named with arbitrary names. But '+' and '-' are not names. From the original question, it is inferred that object properties just need be keyed, not named.

argumental reference inconsistency in javascript

I have recently encountered a nasty issue in JS.
Let say we pass a map, an array of objects to a function f.
var o=[{a:0}];
function f(a){
for(var i in a){
if (a.hasOwnProperty(i)){
a[i]=null;
}
}
return a;
};
var outp=f(o);
alert(outp[0]+" === "+o[0]+" : "+(outp[0]===o[0]));
// here we expect loose equality, and equality in type,
//furthermore it should identically equal as well, and we got right!
But, we can not pass total responsibility of an object to a function as argument, same like in functional paradigm o=(function(o){return o})(), because any kind of modification to o is not referenced!
var o=[];
function ff(a){
return (a=undefined);
};
var outp=ff(o);
alert(outp+" === "+o.constructor+" : "+(outp===o));
// here we expect true, but we got false!
Why is the above described reference loss and
presumably different referencce handling in the second use case,
though in both case, functions got the array argument in the 0. position?
Javascript always passes arguments by value, so this won't work:
function foo(x) {
x = 100;
}
y = 5
foo(y)
y == 100 // nope
However this does work:
function foo(x) {
x.bar = 100;
}
y = {}
foo(y)
y.bar == 100 // yes
In the second snippet x is still passed by value, but this very value is a reference (pointer) to an object. So it's possible in a function to dereference it and access what's "inside" the object.

Understanding d3.js source: stuck at function.call() and "=+"

In the source code of d3.layout.force, line 158, there is this code
force.charge = function(x) {
if (!arguments.length) return charge;
charge = typeof x === "function" ? x : +x;
return force;
};
Now, if you go to line 225, you will see
charges = [];
if (typeof charge === "function") {
for (i = 0; i < n; ++i) {
charges[i] = +charge.call(this, nodes[i], i);
}
} else {
for (i = 0; i < n; ++i) {
charges[i] = charge;
}
}
What I did not understand here is the line
charges[i] = +charge.call(this, nodes[i], i);
I am new to JavaScript and can not understand what's going on here.
As far as I understood charge takes only 1 argument (x). Here "this" is passed to give the context of current object but what about the other two? Which one of "nodes[i]" and "i" is taken as "x" ?
Again what is "= +" doing here?
Check out the MDN listings for call, apply and bind.
It's a tough concept to wrap your head around but what's happening in call and apply is that you're choosing to execute a function in a different "context."
I say "context" with quotes as "execution context" has an exact meaning in JS and this isn't it. I don't have a great word for it but what's happening here is that you're making swapping out the this object when executing the function.
This might help:
var obj = { foo: "bar" };
method.call( obj, "arg" );
function method( arg ) {
console.log( this.foo ); #bar
console.log( arg ); #"arg"
}
I think you'll find your answer here.
Basically, it's converting this:
function(){ return +new Date; }
into this:
function(){ return Number(new Date); }
Essentially, it is converting the argument into a number, and adding it to the previous value.
More reading about this here
You have to follow charge more carefully. It is variable defined in line 11:
charge = -30,
The function force.charge which you quoted is for setting the charge, it is not the function referred to in +charge.call(this, nodes[i], i);. Have a look at the second line of force.charge:
charge = typeof x === "function" ? x : +x;
x can be a function (callback) you pass, to dynamically calculate the charge. The current node (nodes[i]) and the index of the node (i) will be passed to this callback, so that you can calculate the charge dynamically based on these values:
force.charge(function(node, index) {
return index * 2;
});
x (and therefore charge) can also be a number or numerical string. That's why it is tested beforehand whether charge is a function or not:
if (typeof charge === "function") {
// function so we call it and pass the current node and index
} else {
// static value, the same for each node
}
Apert from that, you can always pass any number of arguments to a function, no matter how many parameters it has defined. For example:
function foo() {
alert([].join.call(null, arguments));
}
foo('a', 'b');
will alert a,b.
To answer your questions: The arguments passed to .call() [MDN] or .apply() [MDN] are passed in the same order to the function. So if I have a function function foo(a, b, c) then foo.call(null, x, y) would pass x as a and y as b (c would be undefined).
The + operator is the unary plus operator [MDN], which simply converts the operand into a number.

Categories

Resources