how to use call function in Javascript? [duplicate] - javascript

This question already has answers here:
When should I use arrow functions in ECMAScript 6?
(9 answers)
Can you bind 'this' in an arrow function?
(14 answers)
Are 'Arrow Functions' and 'Functions' equivalent / interchangeable?
(4 answers)
Closed 5 years ago.
I'm being a bit puzzled when I try to convert a simple ES5 code to ES6.
Let's say I have this block of code:
var obj = {num: 2}
var addToThis = function (a, b, c) {
return this.num + a + b + c
}
// call
console.log(addToThis.call(obj, 1, 2, 3))
// apply
const arr = [1, 2, 3]
console.log(addToThis.apply(obj, arr))
// bind
const bound = addToThis.bind(obj)
console.log(bound(1, 2, 3))
Everything above runs smoothly and as expected.
But as soon as I start using ES6 features such as const and arrow function, like this:
const obj = {num: 2}
const addToThis = (a, b, c) => {
return this.num + a + b + c
}
It doesn't work anymore and throws an error: Cannot read property 'num' of undefined.
Can someone please explain why this doesn't work anymore?

Lambda functions (arrow functions) doesn't create new functional context and use context of a calling function.
So "this" refers to a parent context. If there's no 'num' variable than it's undefined.
Usually it's really convenient because most of the time you use one context instead of creating a new one in every function you create. In my opinion call/apply/bind is completely confusing and lambda functions makes it unnecessary.

Related

JavaScript Object Property Instantiation [duplicate]

This question already has answers here:
Javascript object initialization and evaluation order [duplicate]
(2 answers)
Are Javascript Object Properties assigned in order?
(5 answers)
Closed 2 years ago.
If you have an object where the properties are created by calling a function or a constructor, is the order of execution of these guaranteed?
Example:
const testObject = {
foo: new Date().valueOf(),
bar: new Date().valueOf()
};
console.log(testObject.foo > testObject.bar);
Is it ever possible that foo will be greater than bar?
You can try it for yourself. In the latest firefox and chrome it appears to be evaluated as written:
let i = 0;
const counter = () => i++;
const testObj = {
a: counter(),
b: counter(),
c: counter(),
d: counter(),
e: counter()
}
console.log(testObj)

Overriding function named params in Javascript? [duplicate]

This question already has answers here:
Where can I get info on the object parameter syntax for JavaScript functions?
(1 answer)
ES6 Object Destructuring Default Parameters
(1 answer)
Closed 2 years ago.
function lookupRecord2({value1 = "blue", value2 = 7}) {
console.log('theValues');
console.log(value1);
console.log(value2);
}
lookupRecord2( { value1: 'pink', value2: 9 } );
I've read that Javascript doesn't allow for named parameters so I'm confused how the above code works. What is happening here that's allowing me to override the params?
I think what's confusing is that the params are assigned with "=" whereas the object I'm passing uses ":" ...
ADDED:
I know this is a form of destructuring, but I still can't make sense of it b/c it's in the function declaration.
function des({ a = 1, b = 2 } = {}) {
console.log(a);
console.log(b);
}
des();
This is a destructing syntax where we're able to pass default values.
It works everywhere, not just in function declarations.
{ a = 1, b = 2 } = { b:3 }
// assigns 1 to "a" and because "b" already exists, "b" is 3
MORE INFO HERE: can someone explain this seemingly weird assignment `{key=value} = argument`

JavaScript array expressions return object literal in one line [duplicate]

This question already has answers here:
ECMAScript 6 arrow function that returns an object
(6 answers)
Closed 3 years ago.
Its known that someone can make a one-line array function like this to return the single value:
var func = (x) => x + 1 //func(2) == 3
and you can also make multi-line array-functions, whose values need to be manually returned:
var funcMultiline = (x) => {
var result = 1;
result += x;
return result;
}
funcMultiline(4) == 5; //true
So the question:
let's say I want to return a new object in one line, if I use the brackets, then the array-function is treated like a multi-line function, and doesn't actually return the object-literal. Is there any direct way to create an object literal in, lets say, a map function? Like:
[...Array(25)].map(e => {x: 5, y:10}) //this is a syntax error, but how can I make this work
Returning object literals using the concise body syntax params => {object:literal} will not work as expected.
You have to wrap the object literal with parenthesis:
var res = [...Array(25)].map(e => ({x: 5, y:10}))
console.log(res);

Why is the "this" value different? [duplicate]

This question already has answers here:
JavaScript object functions and `this` when unbound and returned in expression/parens
(2 answers)
How does the "this" keyword work, and when should it be used?
(22 answers)
Closed 4 years ago.
Here is an example where o.foo(); is 3 but (p.foo = o.foo)(); is 2?
function foo() {
console.log( this.a );
}
var a = 2;
var o = { a: 3, foo: foo };
var p = { a: 4 };
o.foo(); // 3
(p.foo = o.foo)(); // 2”
If I do something like this then I get 4 which is what I want. How are those 2 examples are different?
p.foo = o.foo;
p.foo(); // 4
This :
(p.foo = o.foo)();
Is pretty much the same as doing this:
d = (p.foo = o.foo);
d();
Basically what it says is that the return of an assignment is the function itself in the global context. On which a is 2.
actually your code is wrong because your snippet doesnt run, you should be doing the following: console.log( this.a );
and now, lets see how this works.
function foo() {
console.log( this.a );
}
this will call this in the scope of the caller, so lets investigate our results.
so, you are setting a=2 globally, and then in the objects o.a = 3 and p.a=4
so:
calling o.foo it will return 3 because this is pointing to o
calling p.foo it will return 4 because this is pointing to p
BUT
calling (p.foo = o.foo)(); it will return 2 because it is not pointing to any object, so it will take your scope (which is the global scope) and then it will return 2.
if you go with:
p.foo = o.foo
p.foo() //4
it will return 4 successfully because it is pointing to p.
Performing that assignment operation before the function call here:
(p.foo = o.foo)();
causes the object reference to p to be lost. If you instead wrote
p.foo = o.foo;
p.foo();
you'd get 4. As it is, you get 2 because the value of this will be window in the function.
Because that parenthesized subexpression is an assignment result, there's no object lookup directly associated with the result of the expression — the value of the assignment expression is just the function reference without a contextual object. Thus the runtime doesn't have a value to use for this when it calls the function, so this is bound by default to window (or the global object in whatever context).

Function.prototype.call doesn't work inside higher order functions and/or arrow functions? [duplicate]

This question already has answers here:
Arrow Functions and This [duplicate]
(5 answers)
Are 'Arrow Functions' and 'Functions' equivalent / interchangeable?
(4 answers)
Closed 5 years ago.
I try to use higher order functions (map, find, filter, reduce, etc) on an array of objects. In the callback I need to use a function inside of those objects, with the correct 'this' argument. Something like this:
const something = [
{
x: 42,
f: y => this.x + y
},
{
x: 13,
f: y => this.x - y
}
]
const result = something.map(obj => obj.f.call(obj, 10));
I expected result to be [52, 3], but I've got this:
TypeError: Cannot read property 'x' of undefined
Could you help me
understand what happened here
forward 'this' inside my function?
Thanks!

Categories