Why does the anonymous callback work but the named callback fail? - javascript

I have the following code:
this.leaves.forEach(this.leafFloat(leaf));
private leafFloat(leaf: Phaser.Physics.Arcade.Sprite): () => void {
return function() {
leaf.setVelocityX(-50);
}
}
But I get the error "Cannot find name 'leaf'".
If I make the callback an anonymous function like so:
this.leaves.forEach((leaf) => { leaf.setVelocityX(-50)});
It runs exactly as expected, why is this?

It's because in the first line you pass as a parameter the variable leaf, which is not defined previously.
this.leaves.forEach(this.leafFloat(leaf));
// ^- here
However, in the lambda function, you are calling the parameter leaf, which is correctly defined.
this.leaves.forEach((leaf) => { leaf.setVelocityX(-50)});
// ^-defined ^-called

Related

CallBack function execution in javascript?

function nestedFunction() {
console.log('nested function');
}
function firstFunction(cb) {
cb(nestedFunction());
}
function resetRouter() {
setTimeout(() => {
console.log('hello');
firstFunction(() => {
console.log('inside oye oyr');
});
}, 1000);
}
resetRouter();
This is my function . In this first reset Router is executed. Inside resetRouter after 1 second my first function is getting executed. First function takes a callback function as a param . Till here the things are clearer to me. But when the firstFunction is getting called it recieves a cb as a param , we are executing the callBackfunction and inside that callback function we are passing the nested function . So here first our nested function gets executed then the cb(callBack gets executed). So how is this being executed. Please someone explain its execution in a more clearer and easy way.
function firstFunction(cb) {
cb(nestedFunction());
}
You're not passing nestedFunction. You're passing the value resulting from invoking nestedFunction (see the () after it). If you just want to pass a reference to nestedFunction into cb, just pass the name.
function firstFunction(cb) {
cb(nestedFunction);
}
This is what happens:
1: resetRouter gets called.
2: In 1 second:
a. resetRouter logs "hello" in the console.
b. call `firstFunction` with the argment - () => console.log("inside oye oyr")
note: the callback function doesn't get executed in this step.
c. nestedFunction gets called.
d. nestedFunction logs "nested function"
e. the callback in `b` gets called with one argument - undefined
f. finally, `b` logs "inside oye oyr" in the console.
Output:
hello // from resetRouter
nested function // from nestedFunction
inside oye oyr // from firstFunction callback.

Jasmine testing matcher for throw someObject

I have a function which throws some object in certain cases. I wrote a jasmine expect matcher with toThrow but its not working. Not sure why its failing. Any help will be appreciated.
fit("The 'toThrow' matcher is for some object", function() {
function baz(x) { // this is the function to test
if(x === 1) {
return 1;
} else {
throw {status: 515};
}
};
expect(baz(1)).toBe(1); // matched perfect.
expect(baz(2)).toThrow({status: 515}); // failing with message Error: "[object Object] thrown"
});
How to write matcher for function call baz(2)??
According to the documentation, you have to give the reference to the function to expect, not the return value of the function.
see https://jasmine.github.io/api/3.5/matchers.html#toThrow
Example
function error() {
throw 'ERROR';
}
expect(error).toThrow('ERROR')
For your case, you can wrap your function call into another function. You can directly inline the declaration of that function inside the expect argument:
expect(() => baz(2)).toThrow({status: 515});
// equivalent with
expect(function(){ baz(2) }).toThrow({status: 515});
Another way is to use .bind to attach parameters to the function without calling it.
expect(baz.bind(null, 2)).toThrow({status: 515});
// ^^^^ ^
// context first parameter

I want to understand how function creation in javascript with following patter doesn't throw error

var fn = function example(){
console.error('Hello');
}
I want to understand how function initialization with name 'example' doesn't throw error during execution.
Secondly i understand the flow of 'fn' holds the reference of the function i'm assigning to it, were when i execute 'fn()' it works, were as when i try 'example()' it doesn't print "Hello"
Help me to know how that stuff works !!
Because you assign only name example to anonymous function. You do not create actual example function.
Your fn holds function that has it's name as example
var fn = function example() {
console.error('Hello');
}
var fn2 = function () {
console.error('Hello 2');
}
function example2() {
console.error('Hello 3');
}
console.log(fn.name);
console.log(fn2.name);
console.log(example2.name);
console.log("");
console.log(window['example']);
console.log(window['fn']);
console.log(window['fn2']);
console.log(window['example2']);

JavaScript: Callback Accessing another parameter

In this example it seems that a callback is accessing another parameter (without having to provide the argument again).
Excerpt from the link above
var SimplePropertyRetriever = {
getPrototypeEnumerables: function(obj) {
return this._getPropertyNames(obj, false, true, this._enumerable);
},
_enumerable: function(obj, prop) {
return obj.propertyIsEnumerable(prop);
},
_getPropertyNames: function getAllPropertyNames(obj, iterateSelfBool, iteratePrototypeBool, includePropCb) {
...
}
}
As seen:
this._enumerable is passed to _getPropertyNames
_enumerable accepts a parameter called obj
obj is not explicitly passed down though, so it seems that when the callback is passed to _getPropertyNames it somehow accesses its first argument, which is obj
To test it, I tried the below, which did not work.
function myFunc2(para, callback) {
console.log(`Para: ${para}`);
callback();
}
myFunc2(42, (para) => console.log(para));
Any idea what I am missing here?
I would suggest you understand Closures and Variable Scopes in JavaScript.
For the code snippet you mentioned above, since your callback needs an arg 'para' you can pass it and log it. If you don't want to pass it you can just add it to global object( 'window' object in case of browser).
This is because your anonymous callback function expects 'para' variable first in it's own body, next it will try to search in it's parent's body which in this case is global object.
For the below example,
function myFunc2(para, callback) {
window.para = para;
console.log(`Para: ${para}`);
callback();
}
myFunc2(42, () => console.log(para));

node: using chai's expect.to.throw on a function that takes arguments

I need to call expect().to.throw() on a function that takes arguments. For example, say I have the following:
var func = function(x) {
if (x > 1) {
throw new Error()
} else {
console.log('hello')
}
}
expect(func).to.throw()
This fails, because it calls func without an argument, meaning it will never throw an error. But if I call expect(func(2)).to.throw(), I get AssertionError: expected undefined to be a function. The function gets called and the return value is passed to expect.
How can I use expect().to.throw() and give the included function arguments. Is the only way to do it with an anonymous function, like expect(() => {func(2)}).to.throw()?
This is from the chai docs:
If you need to assert that your function fn throws when passed certain arguments, then wrap a call to fn inside of another function.
expect(function () { fn(42); }).to.throw(); // Function expression
expect(() => fn(42)).to.throw(); // ES6 arrow function

Categories

Resources