In Chrome console, I am getting this error,
Uncaught ReferenceError: operations is not defined
at :1:1
(anonymous) # VM118:1
yet this snippet runs here when I pasted it in.
What am I missing? I am trying to declare 4 functions, and capture them in a variable as an array, and then loop over that array.
function add(x, y) {
return x + y;
}
const subtract = function(x, y) {
return x - y;
}
function multiply(x, y) {
return x * y;
}
const divide = function(x, y) {
return x / y;
}
//We can store functions in an array!
const operations = [add, subtract, multiply, divide];
//Loop over all the functions in operations
for (let func of operations) {
let result = func(30, 5); //execute func!
console.log(result);
}
Related
I know in JavaScript only function declarations are hoisted, which means it should print 30 after running the function sum.
However it says diff is not defined, shouldn't it be hoisted?
sum(10, 20);
diff(10, 20);
function sum(x, y) {
return x + y;
}
let diff = function(x, y) {
return x - y;
}
It's because as you said, only function declarations are hoisted, not function expressions (assigning a nameless function to a variable). Following code works:
sum(10, 20);
diff(10, 20);
function sum(x, y) {
return x + y;
}
function diff(x, y) {
return x - y;
}
To declare diff the way you did, you must lift it to the top of your code:
let diff = function(x, y) {
return x - y;
}
sum(10, 20);
diff(10, 20);
function sum(x, y) {
return x + y;
}
Yes, let and const are hoisted but you cannot access them before the actual declaration is evaluated at runtime.
You are accessing the function before you initialize it.
So this should work,
let diff = function(x, y) {
return x - y;
}
function sum(x, y) {
return x + y;
}
console.log(sum(10, 20));
console.log(diff(10, 20));
let diff will hoist but at the moment when function diff(10, 20); will be called variable diff will not jet be defined with the function.
Google this topic function declaration vs function expression
Because Function Expressions are not hoisted like Function Declarations
Function expressions in JavaScript are
not hoisted, unlike function declarations. You can't use function
expressions before you create them:
console.log(notHoisted) // undefined
// even though the variable name is hoisted, the definition isn't. so it's undefined.
notHoisted(); // TypeError: notHoisted is not a function
var notHoisted = function() {
console.log('bar');
};
https://developer.mozilla.org/en-US/docs/web/JavaScript/Reference/Operators/function#function_expression_hoisting
You will need to use a Function Declaration if you want it to be hoisted.
T want to divide a method into two, so that it can be used by two methods with different arguments.
What am I trying to do?
I have a method named convert_point that takes values x and y based on a click on a canvas and then converts that to x, y and z values as an array.
add_point_at = (x, y) => {
this.props.convert_point([x, y]).then(converted_point => {
let next;
let some_var = this.state.some_var;
if (some_var === undefined) {
this.method1();
next = this.add(this.props.drawings);
some_var = next.paths.length - 1;
this.setState({
some_var: some_var,
draft_point: {x: x, y: y},//seems like this x and y values
needs to replaced as well...
});
} else {
next = this.props.drawings;
this.setState({
some_var: undefined,
});
}
const variable = next.paths[some_var];
next_drawings = this.add_path(
next, converted_point[0], converted_point[1],
converted_point[2]);
this.props.on_drawings_changed(next_drawings);
}).catch(some_method_called);
};
The above method accepts x and y values, so basically it is called by another function like below. Here x and y are, say, 20 and 30 and when given to this.props.convert_point method in add_point_at, the output is say [11.2, -13, 45], so basically converted_point given to the then method is [11.2, -13, 45]:
handle_click = (x, y) => {
this.add_point_at(x,y);
}
This works fine. Now there is a situation where I have x, y and z values already and want to call the add_point_at method… So I divided the add_point_at method as below:
add_point_at = (x, y) => {
this.props.convert_point([x,
y]).then(this.call_another_method).catch(some_method_called);
call_another_method = (converted_point) => {
let next;
let some_var = this.state.some_var;
if (some_var === undefined) {
this.method1();
next = this.add(this.props.drawings);
some_var = next.paths.length - 1;
this.setState({
some_var: some_var,
draft_point: {x: x, y: y},// x and y values are unknown
});
console.log("last statement in if");
} else {
next = this.props.drawings;
this.setState({
some_var: undefined,
});
}
console.log("first statement after else");
const variable = next.paths[some_var];
next_drawings = this.add_path(
next, converted_point[0], converted_point[1],
converted_point[2]);
this.props.on_drawings_changed(next_drawings);
};
So if I have x, y and z values already, I directly call:
this.call_another_method(converted_point);
If I have only x and y values, I call
this.add_point_at(x, y);
…so that this converts x, y to x, y, z values using the this.props.convert_point method.
But after dividing the method, it doesn't work. I don't see any console error. To debug, I tried to add console statements as seen in code above, but it is not logged to the console. Not sure why.
Could someone help me understand where the problem is?
EDIT: i realised that the problem is with the x and y values undefined in the splitted method...how can i refactor this method such that x and y values are replaced with something.
Below is a specific use case of using a normal and a curried function. Are there any advantages for using either if you only using two arguments?
//Normal Function
function add(x, y) {
return x + y;
}
//Curried Function
function add1(x) {
return function add2(y) {
return x + y;
}
}
Here's a small example:
let add = (x, y) => x + y;
let addc = x => y => x + y;
// add 5 to every element
result = [1,2,3,4,5].map(x => add(x, 5)) // dirty and tedious
result = [1,2,3,4,5].map(addc(5)) // nice and tidy
In general, curried functions allow to express the logic in a "point-free" style, that is, as a combination of functions, without using variables, arguments and similar constructs.
This question already has answers here:
Is JavaScript a pass-by-reference or pass-by-value language?
(33 answers)
Closed 6 years ago.
I am not able to achieve the desired result for this swap function below, where I want the values printed as 3,2
function swap(x,y){
var t = x;
x = y;
y = t;
}
console.log(swap(2,3));
Any clue will be appreciated !
Your function is swapping the values internally, but the function does not return a value.
The following method returns an array of values in reverse order of what was supplied.
function swap(x, y) {
var t = x;
x = y;
y = t;
return [x, y];
}
console.log(swap(2, 3));
However, you could easily do something like the following snippet, because - based on your supplied code - there seems to be no need to actually swap the values of the arguments.
function swap(x, y) {
return [y, x];
}
console.log(swap(2, 3));
If you don't actually need the values to swap:
function swap (x, y)
{
return [y, x];
}
If you do need the values to swap, but you don't want to declare another variable:
function swap (x, y)
{
x = x + y;
y = x - y;
x = x - y;
return [x, y];
}
I got two functions called on mouse events:
function menuBtnOver(e){
var b = e.data;
b.setPosition(b.x, b.y+5);
}
function menuBtnOut(e){
var b = e.data;
b.setPosition(b.x, b.y-5);
}
and:
setPosition:function(x, y) {
if(!x) x = 0;
if(!y) y = 0;
this.element.css("left", x);
this.element.css("top", y);
}
element property is a jQuery object.
It is working ok but i want to animate this. How can i do this with TweenLite?
I've tried following code:
function menuBtnOver(e){
TweenLite.to(e.data, 1, {top:500});
}
As well as this:
function menuBtnOver(e){
TweenLite.to(e.data.getElement(), 1, {top:500});
}
and many other combinations but none of them worked.
Only on method which partially work is this:
function menuBtnOver(e){
TweenLite.to(e.data, 1, {y:400, onUpdate:e.data.setPosition, onUpdateParams:[e.data.x, e.data.y]});
}
But it work only on fist button when I roll over and (after any time) roll out, it moves directly to given position (without tween) and then the tween goes forever giving me error each time(at least - I couldn't get any errors or anything with other attempts).
Uncaught TypeError: Cannot read property 'css' of undefined
at: this.element.css("left", x);
Update
I figured out what is going on.
I've changed code as so:
function menuBtnOver(e){
TweenLite.to(e.data, 1, {y:400, onUpdate:e.data.setPosition, onUpdateParams:[e.data.x, e.data.y], onUpdateScope:e.data});
}
But the problem with this is that arguments to update function which I set to e.data.y/x aren't dynamic references and always stay as those exact values from menuBtnOver state. So the tween works if i change setPosition function to:
setPosition:function(x, y) {
if(!x) x = 0;
if(!y) y = 0;
this.element.css("left", this.x);
this.element.css("top", this.y);
}
But obviously this is not what I want to do.
So I have option to make something like this:
MenuButton.prototype = {
setPosition:function(x, y) {
if(!x) x = 0;
if(!y) y = 0;
this.x = x; this.y = y;
this.element.css("left", x);
this.element.css("top", y);
},
updatePosition:function(){
this.element.css("left", this.x);
this.element.css("top", this.y);
}
}
function menuBtnOver(e){
TweenLite.to(e.data, 1, {y:400, onUpdate:e.data.updatePosition, onUpdateScope:e.data});
}
Or define external update function in similar manner. The question still stays the same so is there a simple way to do this simpler. Does GS tween has any mechanic which automate this process?
Thanks to everyone for attention :)
this in setPosition is referring to that function and not the this of the onClick event.
you need to do pass this to setPosition. As in the example below, where I passed it as self in the function setPosition.
function menuBtnOver(e){
var b = e.data;
b.setPosition(this, b.x, b.y+5);
}
function menuBtnOut(e){
var b = e.data;
b.setPosition(this, b.x, b.y-5);
}
and:
setPosition:function(self, x, y) {
if(!x) x = 0;
if(!y) y = 0;
self.element.css("left", x);
self.element.css("top", y);
}
this always refernces the function in which is was called. as you can read about her. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this
So you can pass this in a function as a variable.