I need to call a function with the same parameter's values to refresh a ChartJs with a new daterange.
The _reportDateStart and _reportDateEnd are updated outside of the function, so I need to recall the function so the chart is updated with the new data.
The script is:
var _reportDateStart;
var _reportDateEnd;
var _loadChart = function (chartLabel, queryMetrics, queryDimensions) {}
The call is made like this:
_loadChart("Visits", "ga:sessions", "ga:date,ga:nthDay");
But can also be:
_loadChart("Users", "ga:users", "ga:date,ga:nthDay");
Declare globally accessible variables and assign the parameters on every call that way you can call the function with those variables again:
Example:
var param1,param2,param3;
var _loadChart = function(a, b, c){
param1 = a;
param2 = b;
param3 = c;
//rest of the code.
};
function callTheFunctionAgain(){
_loadChart(a, b, c);
}
_loadChart("Visits", "ga:sessions", "ga:date,ga:nthDay");
callTheFunctionAgain();
to do this you can create a new function with bound param as you wish like this var _loadChartBounded = _loadChart.bind(null, "Visits", "ga:sessions", "ga:date,ga:nthDay")
then every time you call _loadChartBounded() it will get the same param
We already have global variables and .bind()
I will throw in another solution which uses a closure
For an explanation on how these work, head over to this question and its excellent answers:
How do JavaScript closures work?
// This is only an example.
// Please change the variable names to something more meaningful :)
var _loadContent = (function() {
var _a, _b, _c;
return function(a, b, c) {
if (typeof _a === "undefined") {
_a = a;
_b = b;
_c = c;
}
console.log(_a, _b, _c);
}
}());
_loadContent(1, 2, 3);
_loadContent(4, 5, 6);
_loadContent();
For those arriving in the now (15 Jun 2020), here's the most robust way to call a function from within it:
let fn = (a, b, c) => {
/* fn's content */
fn(...arguments);
}
This works great if you don't know what the parameters will be (user input), or simply do not want to have to change the parameters in multiple places when refactoring the code.
Reference
Related
I want to execute my add function with the following Code. But I'm not getting the right syntax.
I have already tried x.add(3,4) and x().add(3,4), but that doesn't work.
Please let me know where I am going wrong.
<html>
<body>
<p>
After a function has been stored in a variable,
the variable can be used as a function:
</p>
<p id="demo">
hello
</p>
<script>
var x = function () {
var add = function(a, b) { return a + b };
var mul = function(a, b) { return a * b };
}();
document.getElementById("demo").innerHTML = x.add(3,4);
</script>
</body>
</html>
It seems you want x to be an object. The correct syntax for that is
var x = {
add: function(a,b){return a + b},
mul: function(a,b){return a * b},
};
Or if you insist on using an IIFE (because you're doing more things in that scope than you've shown), then you'd do
var x = (function () {
function add(a,b){return a + b}
function mul(a,b){return a * b}
return {add, mul};
}());
Functions defined within other functions aren't automatically available to outside code. Their default is to exist the same duration as any other local variable, available for garbage collection when the outer function is done executing.
To keep them around, you'll need to specify how you want to make them available. One option for that is to return them, adding a structure to hold them both:
var x = function () {
return {
add: function(a,b){return a + b},
mul: function(a,b){return a * b},
};
}();
Though, so far at least, the outer function isn't strictly necessary and could possibly be removed:
var x = {
add: function(a,b){return a + b},
mul: function(a,b){return a * b},
};
See the comments inline below:
// You can set the function up as a "constructor function",
// meaning that an object instance will be constructed from the
// invocation of the function. Standard convention is to use
// PascalCase for constructor function names:
function X() {
// Later, when an instance of this object is made,
// members of the object can be gotten by identifying
// them as going along with "this" object instance.
// There is more to know about this (ie. properties are
// created as I'm showing here, but methods are often
// added to the function's prototoype).
this.add = function(a,b){return a + b};
this.mul = function(a,b){return a * b};
}
// Use the function to construct an object instance
let instance = new X();
// Then, use that instance and its associated members.
// FYI: Don't use .innerHTML when you aren't getting/setting
// any HTML. Use .textContent for raw text.
document.getElementById("demo").textContent = "Add: " + instance.add(3,4);
document.getElementById("demo").textContent += " | Multiply: " + instance.mul(3,4);
<p>After a function has been stored in a variable,
the variable can be used as a function:</p>
<p id="demo">hello</p>
What you are doing here is defining a function named x, and defining two variables inside that function, named add and mul. Due to the rules that JavaScript follows when it comes to item scope (Especially in the context of functions, see the section Function Scope), these variables are inaccessible outside of the function. To access them, you will need to have the function return an object defining them:
var x = function() {
var add = function(a,b){return a + b};
var mul = function(a,b){return a * b};
return {
add: add,
mul: mul
};
}
These can now be accessed by calling the function, which will return these two values:
var y = x();
document.getElementById("demo").innerHTML = y.add(3,4);
In side function if you want to declare public variables to constuctor use this. And make sure to put new to create new instance of your constructor
var x = new function () {
this.add = function(a,b){return a + b};
this.mul = function(a,b){return a * b};
};
console.log(x.add(1,3));
console.log(x.mul(5,3));
I was wondering if there is any way to access variables trapped by closure in a function from outside the function; e.g. if I have:
A = function(b) {
var c = function() {//some code using b};
foo: function() {
//do things with c;
}
}
is there any way to get access to c in an instance of A. Something like:
var a_inst = new A(123);
var my_c = somejavascriptmagic(a_inst);
A simple eval inside the closure scope can still access all the variables:
function Auth(username)
{
var password = "trustno1";
this.getUsername = function() { return username }
this.eval = function(name) { return eval(name) }
}
auth = new Auth("Mulder")
auth.eval("username") // will print "Mulder"
auth.eval("password") // will print "trustno1"
But you cannot directly overwrite a method, which is accessing closure scope (like getUsername()), you need a simple eval-trick also:
auth.eval("this.getUsername = " + function() {
return "Hacked " + username;
}.toSource());
auth.getUsername(); // will print "Hacked Mulder"
Variables within a closure aren't directly accessible from the outside by any means. However, closures within that closure that have the variable in scope can access them, and if you make those closures accessible from the outside, it's almost as good.
Here's an example:
var A = function(b) {
var c = b + 100;
this.access_c = function(value) {
// Function sets c if value is provided, but only returns c if no value
// is provided
if(arguments.length > 0)
c = value;
return c;
};
this.twain = function() {
return 2 * c;
};
};
var a_inst = new A(123);
var my_c = a_inst.access_c();
// my_c now contains 223
var my_2c = a_inst.twain();
// my_2c contains 446
a_inst.access_c(5);
// c in closure is now equal to 5
var newer_2c = a_inst.twain();
// newer_2c contains 10
Hopefully that's slightly useful to you...
Answers above are correct, but they also imply that you'll have to modify the function to see those closed variables.
Redefining the function with the getter methods will do the task.
You can do it dynamically.
See the example below
function alertMe() {
var message = "Hello world";
console.log(message);
}
//adding the getter for 'message'
var newFun = newFun.substring(0, newFun.lastIndexOf("}")) + ";" + "this.getMessage = function () {return message;};" + "}";
//redefining alertMe
eval(newFun);
var b = new alertMe();
now you can access message by calling b.getMesage()
Of course you'll have to deal with multiple calls to alertMe, but its just a simple piece of code proving that you can do it.
The whole point to that pattern is to prevent 'c' from being accessed externally. But you can access foo() as a method, so make it that it will see 'c' in its scope:
A = function(b) {
var c = function() {//some code using b};
this.foo = function() {
return c();
}
}
No, not without a getter function on A which returns c
If you only need access to certain variables and you can change the core code there's one easy answer that won't slowdown your code or reasons you made it a closure in any significant way. You just make a reference in the global scope to it basically.
(function($){
let myClosedOffObj = {
"you can't get me":"haha getting me would be useful but you can't cuz someone designed this wrong"
};
window.myClosedOffObj = myClosedOffObj;
})(jQuery);
myClosedOffObj["you can't get me"] = "Got you now sucker";
Proof of concept: https://jsfiddle.net/05dxjugo/
This will work with functions or "methods" too.
If none of the above is possible in your script, a very hacky solution is to store it in a hidden html-object:
// store inside of closure
html.innerHTML+='<div id="hiddenStore" style="display:none"></div>';
o=document.getElementById("hiddenStore")
o.innerHTML="store this in closure"
and outside you can read it with
document.getElementById("hiddenStore").innerHTML
You should be able to use an if statement and do something like:
if(VaraiableBeingPasses === "somethingUniqe") {
return theValueOfC;
}
My code is like this:
Example 1:
var fn = (function () {
function fn (a, b, c) {
/* CODE HERE */
};
return fn;
})();
fn(a, b, c);
Example 2:
var fn = function fn (a, b, c) {};
fn(a, b, c);
what is the difference between this two calls? I'm trying to refact some codes. When i try to put out the fn function like the second example, it fails.
The most common use case for IIFE is to create a closure with some private variables inside of it. For example:
var counter = (function() {
// This variable is private. You cannot change it from the outer code.
var i = 0;
return function() {
return i++;
};
})();
console.log(counter());
console.log(counter());
console.log(counter());
outputs:
0
1
2
So, when you refactor IIFE to regular functions you have to make sure that you deal with closures in the right way.
I am trying to change the definition of a function:
var a = function(){alert('a');};
var b = a;
b = function(){alert('b');};
This results in the variable a keeping it's original assignment i.e. the function producing alert('a').
Is there any way of passing around a reference to a javascript function so that I can alter it later?
Would you expect the value of a to change after the following snippet? Snippet in question:
var a = 10;
var b = a;
var b = 20;
No, right? So why would you expect reassigning b to also affect a?
After line 1, you have a pointing to a function instance:
After line 2, you have a new variable b, also pointing to the same function instance. So now you have two variables, both pointing to the same instance:
After line 3, you have reassigned b to something else (a new function), but a is still pointing to the original function:
You can do what you want by doing something like this:
var func = function() { alert("a"); };
var a = function() { func(); };
var b = a;
func = function() { alert("b"); };
Now calling a() or b() will alert the string b.
Is there any way of passing around a reference to a javascript function so that I can alter it later?
There is no way to do this. Javascript does not have "pointers". It has reference values, and as such, a is a reference to the value of a, not to the memory location of a.
So, for this set of instructions
var a = function(){alert('a');};
var b = a;
b = function(){alert('b');};
this is the progression
//a is stored at some memory location
var a;
//b is stored at some memory location
var b;
//the memory location where a is stored has its value updated
a = function(){alert('a');};
//the memory location where b is stored has its value updated
//from the value stored at a's memory location
b = a;
//the memory location where b is stored has its value updated
b = function(){alert('b');};
You could produce the result you're looking for like this:
var fn = function() { alert('a'); };
var a = function() { fn(); };
var b = a;
fn = function(){ alert('b'); };
This code would produce the desired effect you're looking for because they'll both call fn() and you're changing the common underlying reference.
Could someone please explain the significance of prototype.init function in JavaScript and when it is called during object instantiation?
Why would you want to overwrite it with an empty function?
I am reading the JavaScript for Web book and am stuck on the this for the past few hours...what is piece of code supposed to achieve?
var Class = function(){
var klass = function(){
this.init.apply(this, arguments);
};
klass.prototype.init = function(){};
// Shortcut to access prototype
klass.fn = klass.prototype;
// Shortcut to access class
klass.fn.parent = klass;
...
}
This is just too much magic for me...:)
I'm not sure what you don't understand. init is simply a method like any other, that happens to be called in the constructor and with the same parameters as the constructor. If it's empty then it's just because the person who wrote it didn't need to put anything in it for now but wanted to lay down the groundworks of his class.
function Foo(a, b, c) {
this.init.apply(this, arguments); //This simply calls init with the arguments from Foo
}
Foo.prototype.init = function(a, b, c) {
console.log(a, b, c);
}
var f = new Foo(1, 2, 3); //prints 1 2 3
http://jsfiddle.net/Hmgch/
what is piece of code supposed to achieve?
Confusion.
var Class = function() {
// initialization logic
}
// Shortcut to access prototype
Class.fn = klass.prototype;
// Shortcut to access class
Class.fn.constructor = Class;