Please explain to me why this isn't working when learning about this
& the bind
idea:
var numbers = {
x: 'hi',
y: 'dawd',
z: 'ohgroe',
};
function calc() {
calc.bind(numbers);
return this.x + this.y + this.z;
}
calc();
Please explain to me why this isn't working when learning about this
& the bind
idea:
var numbers = {
x: 'hi',
y: 'dawd',
z: 'ohgroe',
};
function calc() {
calc.bind(numbers);
return this.x + this.y + this.z;
}
calc();
Why is this not returning this simple calculation?
Share Improve this question edited Jan 20, 2021 at 22:44 Hewe 1791 silver badge13 bronze badges asked Oct 12, 2017 at 18:27 HJWHJW 1,0322 gold badges14 silver badges38 bronze badges 3-
3
You do realize
calc.bind(numbers)
returns a new function with bound arguments? It does not changecalc
in place. The best solution would be not to bind inside the function, that makes no sense. Usecalc.call(numbers)
. – Andrew Li Commented Oct 12, 2017 at 18:29 - 1 You catched my attention with the rhyme ;) – Jonas Wilms Commented Oct 12, 2017 at 18:30
-
Have a look at YDJS - this & object prototypes if you want to learn about
this
. – Felix Kling Commented Oct 12, 2017 at 18:39
6 Answers
Reset to default 4bind
returns a function. It doesn't bind the object to the current function. You need to use something like calc.bind(numbers)()
or calc.call(numbers)
.
These calls need to be done outside the function. Here is an example:
var numbers = {
x: 'hi',
y: 'dawd',
z: 'ohgroe',
};
function calc() {
return this.x + this.y + this.z;
}
var result = calc.bind(numbers)();
// OR
// var result = calc.call(numbers);
console.log(result);
this
will be set to the numbers
object only in the invocation of the function returned from .bind()
. It doesn't change the local this
value.
I'm not sure what you were ultimately after when using .bind()
, so I don't know what to suggest for a solution. Maybe describe the original problem you were trying to solve.
Some ways it would work:
function calc() {
return this.x + this.y + this.z;
}
console.log(calc.call(numbers));
//equals calc.bind(numbers)()
Or using with
function calc(){
with(numbers){
return x + y + z;
}
}
console.log(calc());
Or passing numbers:
function calc(nums){
return nums.x + nums.y + nums.z;
}
console.log( calc(numbers));
Then you directly could do that for n values:
fuction calc(nums){
return Object.values(nums).reduce((a,b) => a + b );
}
console.log(calc( {
a:1,b:4,c:5
}));
I feel like giving up on JS
No! Dont do this! JS is one of the coolest languages currently available, and even if its hard to learn it will be worth it i promise ;)
Firstly, it is important to understand bind, call, apply. All let you control what object 'this' points to, but they do it differently.
bind() returns a copy of the function.
call() actually executes the function instead of just creating a copy and can also be passed parameters..
apply() is the same as call() but takes an array when passing in parameters.
With this in mind you can do the following:
var numbers = {
x: 'hi',
y: 'dawd',
z: 'ohgroe',
};
function calc() {
return this.x + this.y + this.z;
}
var boundedCalc = calc.bind(numbers);
boundedCalc();
or
calc.call(numbers);
or
calc.apply(numbers)
Instead of trying to set this
within the function call itself you can define expected parameters to the function
var numbers = {
x: 'hi',
y: 'dawd',
z: 'ohgroe',
};
function calc({x = "", y = "", z = ""} = {}) {
return x + y + z;
}
console.log(calc(numbers));
function calc() {
calc.bind(numbers);
return this.x + this.y + this.z;
}
This creates a new 'this' scope and binds calc to numbers (this does not execute calc, but rather binds numbers to its function call, this does not add it to the this state of the call either). Your calls to this are now doing nothing. Now if you do this
function calc() {
Object.assign(this, numbers);
return this.x + this.y + this.z;
}
X Y and Z are bound to the scope. I have no idea why you would ever do this though, why don't you just do this?
function calc(numbers) {
return numbers.x + numbers.y + numbers.z;
}