I have a function handler:
function handler(data) {
console.log(`1. ${data}`);
}
which I want to append, or redefine, in the same scope as follows:
let oldHandler = handler;
function handler(data) {
oldHandler(data);
console.log(`2. ${data}`);
}
such that when I now call handler:
handler("bar");
I expect the output to be:
1. bar
2. bar
Is this possible?
EDIT
Currently the above results in error: unknown: Identifier 'handler' has already been declared.
Function declarations:
Declare a variable with a matching name
Are hoisted
Use a function expression instead. These do neither of the above.
function handler(data) {
console.log(`1. ${data}`);
}
let oldHandler = handler;
handler = function handler(data) {
oldHandler(data);
console.log(`2. ${data}`);
};
handler("bar");
Related
I'm absolutely out of idea now and i would like anyone with better idea to help give a concise solution to this. here is my code:
Ok what I'm trying to write here is a program that listen to the load event for fetching data from an api and save it in cache, then clear the cache when the user try to exit the browser. using the opt parameter to set when to load and unload the cache outside the method.
class myc {
// ...
async get(url, opt = {}) {
let js, er, data;
if (opt.load === true) {
window.addEventListener('load', getData);
}
if (opt.unload === true) {
window.addEventListener('beforeunload', removeData);
}
async function getData() {
try {
let r = await fetch(url)
if (!r.ok) {
throw new Error(r.statusText)
} else {
js = await r.json();
}
} catch(e) {
er = e.message;
}
if (js) {
localStorage.setItem(key, js);
data = localStorage.getItem(key);
}
// Main problem here (*)
return {
data : data ? data : null,
error: er
};
}
function removeData(){
localSorage.clear();
}
let res = await getData();
window.removeEventListener('load', getData);
window.removeEventListener('beforeunload, removeData);
return res;
}
}
The line with (*) is the main problem here. So how do i return the required value from that function to then be used in another instance
The short answer: you don't.
Even if you returned a value from an event handler, it would have nowhere to go because you don't have access to the thing that actually called the event handler to be able to grab that return value.
Instead, you simply set the value somewhere in the scope you can grab it later.
Since you are in a class, you could simply set it to this.myValue and then grab it with the same.
The only gotcha with that is you have to make sure your event handler is bound to the proper scope.
You can do that one of two ways. On this line:
window.addEventListener('load', getData);
you can bind getData so it looks like this:
window.addEventListener('load', getData.bind(this));
That way the this inside of getData will refer to your class.
Alternatively, you could switch this line:
async function getData() {
to an arrow function syntax:
const getData = async () => {
which will automatically bind to the current context.
Simply use a global variable that you update in the event handler.
Using a call back function (or simply calling another function with the "return" variable value as parameter) to do some more processing is another way of achieving what you probably want.
Example:
async function getData(){
//event handler doing it's task
//create { data : data ? data : null, error: er } as global var
var returnData = { data : data ? data : null, error: er };
//or
functionToDoMoreProcessing({ data : data ? data : null, error: er });
}
It's redundant but I am learning JS and I want to know how it really works.
Returning a function directly from a module
let func1 = function () {
let test = function () {
console.log("1");
}
return {
getTest : test
}
}
Returning a function by using a function
let func1 = function () {
let test = function () {
console.log("1");
}
return {
getTest : function () {
return test;
}
}
}
In the first case, the getTest property of your object points to a function, so calling it this way:
func1().getTest()
Should result in logging 1.
In the second case, getTest returns a function which returns another function, so you'd have to also call the result in order to get 1, this way:
func1().getTest()();
Calling just getTest will return your function object, rather than calling it.
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']);
How to pass the variable from outside to onResourceRequested function?
I am not able to access the variable testvar inside the callback function of onResourceRequested property.
Any idea how to fix this issue?
Below is the sample code I used for testing
var phantom = require("phantom");
var _ph, _page, _outObj;
phantom.create().then(function(ph){
_ph = ph;
return _ph.createPage();
}).then(function(page){
_page = page;
var testvar = "WHY THIS IS NOT PRINTING";
_page.property('onResourceRequested', function (req, networkRequest) {
console.log("THIS LINE WORKS");
console.log(testvar); // THIS DOESNT WORK
});
_page.property('onResourceReceived', function (res) {
//console.log('received: ' + JSON.stringify(res, undefined, 4));
});
return _page.open('https://www.ammaus.com/', function (status) {
if (status !== 'success') {
console.log('FAIL to load the address');
}
_ph.exit();
});
}).then(function(status){
console.log(status);
return _page.property('content')
}).then(function(content){
_page.close();
_ph.exit();
}).catch(function(e){
console.log(e);
});
Use arrow function (ES6) like this:
_page.property('onResourceRequested', (req, networkRequest) => {
console.log("THIS LINE WORKS");
console.log(testvar); // THIS DOESNT WORK
});
An arrow function does not newly define its own this when it's being executed in the global context; instead, the this value of the enclosing execution context is used, equivalent to treating this as closure value.
So I have a function like
func()
{
const curVal = this.curVal;
const callAgain = () => { func(); };
Axios.get('somecontroller/someaction')
.then(response =>
{
const newVal = response.data.curVal;
if(curVal === newVal)
setTimeout(callAgain, 500);
else
// ....
})
.catch(response =>
{
// ...
});
}
and my browser is complaining about the line
const callAgain = () => { func(); };
saying that func is undefined. Any idea why? How can I fix?
You cannot define a function the way you posted.
However, you can for example use the function keyword to define your function:
function func() {
...
}
func(); // it works!
Edit:
According to your comment, this is a object method declaration. In order to make this work, you first need to make sure your browser supports this particular ES2015 feature or if not, you transpile it to valid ES5.
Then you should be able to access the function using this.func():
const callAgain = () => { this.func(); };
In case you are using func() e.g. as a callback for a DOM event, you also have to make sure that this is bound correctly in func, for example by explicitly binding it in the constructor:
constructor() {
...
this.func = this.func.bind(this);
}
Define the function using either of the following:
function func(){ ... }
Or...
var func = function(){ ... }
When you define it like this:
func() { ... }
JavaScript thinks you're trying to execute an existing function called func, and then run the block of code { ... }