How do I call the inner function from outside in the following code ?
(function (){
var funOne = {
funTwo : function (){
var funFour = function(){
console.log('inner function working');
}
},
funThree : function () {
console.log('working');
}
}
funOne.funTwo(); // works
funOne.funThree(); // works again
funOne.funTwo.funFour(); // throwing exception
})();
You have a scoping issue with funFour compounded by trying to define funTwo act as a function (funOne.funTwo()) and an object (funOne.funTwo.funFour()).
Here are 2 options to get access to funFour:
Let funTwo make funFour accessible at the more accessible level (for example, via funOne).
Have funTwo return funFour within an object. You still have to add the parenthesis to actually call funTwo() in your output.
How to change funTwo:
funTwo : function (){
var funFour = function(){
console.log('inner function working');
};
funOne.funFour = funFour; // Option 1
return { 'funFour': funFour }; // Option 2
},
How to call each option:
funOne.funFour(); // Option 1
funOne.funTwo().funFour(); // Option 2
There is no way to access Local variable (var funFour) of function funTwo from outside. If you want to use funFour at outside of function funTwo, you need to declare funFour as Global variable.
Edited code is here.
(function (){
var funFour;
var funOne = {
funTwo : function (){
funFour = function(){
console.log('inner function working');
}
},
funThree : function () {
console.log('working');
}
}
funOne.funTwo(); // works
funOne.funThree(); // works again
funFour(); // Call function funFour here
})();
Related
I am trying to call the function scroll_page inside a function call_scroll_page that is called by setTimeout. And I get error file.js:5 Uncaught TypeError: scroll_page is not a function.
function scroll_page() {
return false;
}
function call_scroll_page() {
var scroll_page = scroll_page();
if(!scroll_page) {
$test = true;
}
}
setTimeout(call_scroll_page, 1000);
var scroll_page
You defined a new variable called scroll_page inside the call_scroll_page function which has masked the global one.
Rename that variable.
It is because you are declaring a var with same name as your function. So inside your function call_scroll_page() scroll_page refers to the local variable. Change your variable name and it will work as intended.
function scroll_page() {
return false;
}
function call_scroll_page() {
var scroll_page_var = scroll_page();
if(!scroll_page_var) {
$test = true;
}
}
setTimeout(call_scroll_page, 1000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
This line is causing the error: var scroll_page = scroll_page();
Do not redeclare something with name of the scroll_page function.
It removes the link to the function, replaced by a variable, calling a function that is no longer "callable by its name".
Try:
function scroll_page() {
return false;
}
function call_scroll_page() {
var fn = scroll_page();
if(!fn) {
$test = true;
}
}
setTimeout(call_scroll_page, 1000);
I'm trying to set up function a nested function that I can call throughout my script, but I keep getting "error undefined is not a function". Perhaps someone can help me with how to do this correctly.
First I set global my variables:
var trigger = document.getElementById('trigger');
var subject = document.getElementById('subject');
Then I create a show/hide function:
var toggleVis = function() {
function showSomething() {
trigger.classList.add("active");
subject.classList.add("active");
}
function hideSomething() {
trigger.classList.remove("active");;
subject.classList.remove("active");
}
}
Then I set my event listener:
trigger.addEventListener('click', function() {
if ( subject.classList.contains("active") ) {
toggleVis.hideSomething();
}
else {
togglePicker.showPicker();
}
});
The reason I'm trying to do it this way is that there will be other triggers for subject on the page that will need access to the show/hide functions.
You can't access the functions inside the function, they are out of scope, you could attach them as properties to the wrapping function, but it looks like you just need an object
var toggleVis = {
showSomething: function() {
trigger.classList.add("active");
subject.classList.add("active");
},
hideSomething: function() {
trigger.classList.remove("active");;
subject.classList.remove("active");
}
}
Your togleVis variable is a function and not an object so you can't do toggleVis.hideSomething(). Try updating your code to :
var toggleVis = (function() {
return {
showSomething : function () {
trigger.classList.add("active");
subject.classList.add("active");
},
hideSomething : function () {
trigger.classList.remove("active");;
subject.classList.remove("active");
}
};
}());
With this toggleVis is now an object with two properties showSomething and hideSomething functions.
In the code below, my return function inside the other function doesn't get run right away, but the first function is. My goal is to have the whole function running immediately.
var windowCheck = (function () {
var switcher = false;
return function () {
console.log(switcher);
if ($window.innerWidth > 480) {
if (!switcher) {
element.perfectScrollbar({
wheelSpeed: scope.wheelSpeed || 50,
wheelPropagation: $parse(attrs.wheelPropagation)() || false,
minScrollbarLength: $parse(attrs.minScrollbarLength)() || false
});
console.log('Plugin On');
switcher = true;
}
}
else {
if (switcher) {
console.log('Plugin Off');
element.perfectScrollbar('destroy');
switcher = false;
}
}
};
}());
The function does indeed run the first time -- an anonymous function runs and it's result is --
Another function!
This 'second' function is then assigned to the value of windowCheck.
And windowCheck won't run until called.
Simply run it after defining it and avoid all the anonymous function mess:
var windowCheck = function() {
...
}
windowCheck();
The code as you have it now defines the windowCheck function and uses a closure to house a private switcher variable. That is all fine. If you want the function that gets defined to be executed, then you just have to add this to the end of what you already have:
windowCheck();
in order to actually execute it immediately.
Let's say I have the following JavaScript
function myGlobalFunction(){
function firstInnerFunction(){
return "rainbows";
}
function secondInnerFunction(){
function innerInnerFunction(){
return "clouds";
}
return innerInnerFunction();
}
return firstInnerFunction(); //valid call
}
Is there anyway I can call firstInnerFunction() in the global scope? If so(and better yet), can I go two levels down and call innerInnerFunction() from the global scope?
What are you trying to achieve in doing something like that? I would suggest something like the following:
var myGlobalFunction = {
var innerInnerFunction() { return "clouds"; }
get firstInnerFunction() { return "rainbows"; }
get secondInnerFunction() { return innerInnerFunction(); }
};
You can then call firstInnerFunction() with something like this:
myGlobalFunction.firstInnerFunction;
as for calling innerInnerFunction() from the global scope, myGlobalFunction.secondInnerFunction() will serve the same purpose as calling innerInnerFunction() directly.
In short, no. JavaScript is function scoped, so everything inside is hidden from the outside. So in order to access the inner functions you'll need to expose them somehow.
Absolute simplest (but ugly) option is to do something like this:
var secondInnerCopy;
function myGlobalFunction(){
function firstInnerFunction(){
return "rainbows";
}
function secondInnerFunction(){
function innerInnerFunction(){
return "clouds";
}
return innerInnerFunction();
}
secondInnerCopy = secondInnerFunction;
return firstInnerFunction(); //valid call
}
myGlobalFunction();
secondInnerCopy(); //valid (only after myGlobalFunction called though)
Better option would be to restructure into an object graph with functions:
var global = {
myGlobalFunction: function(){
return this.inner.firstInnerFunction(); //valid call
},
inner: {
firstInnerFunction: function() {
return "rainbows";
},
secondInnerFunction: function(){
return this.inner.innerInnerFunction();
},
inner: {
innerInnerFunction: function(){
return "clouds";
}
}
}
};
global.myGlobalFunction();
global.inner.inner.innerInnerFunction();
//etc...
I don't think that this is possible, however I could be wrong. You could do something like this to access the nested functions via the top level function.
function A(x) {
function B(y) {
function C(z) {
alert(x + y + z);
}
C(3);
}
B(2);
}
A(1); // alerts 6 (1 + 2 + 3)
Another Example
function addSquares(a,b) {
function square(x) {
return x * x;
}
return square(a) + square(b);
}
a = addSquares(2,3); // returns 13
b = addSquares(3,4); // returns 25
c = addSquares(4,5); // returns 41
Check this link, it has some good information on functions and nested functions in Javascript. Javascript Function Scope
I believe something like this would also work, though I like what Alconja did.
var myGlobalFunction = {
firstInnerFunction: function(){
return "rainbows";
},
secondInnerFunction : function(){
var innerInnerFunction = function(){
return "clouds";
}
var inninnerFuncTwo = function(){
return 'more stuff';
}
return {
inn : innerInnerFunction,
inn2: inninnerFuncTwo
}
}
}
myGlobalFunction.secondInnerFunction().inn();
myGlobalFunction.secondInnerFunction().inn2();
If you want a call to globalFunction to define firstInnerFunction, you can do that as follows
function globalFunction() {
firstInnerFunction = function() { return "rainbows" ; } ;
}
For innerInner function, you can do as follows
function globalFunction() {
firstInnerFunction = function() { return "rainbows" ; } ;
secondInnerFunction = function() {
innerInnerFunction = function() { return "clouds" ; } ; }
}
Now you can do this
globalFunction() ; // defines firstInnerFunction and secondInnerFunction in the global scope
firstInnerFunction() ; // returns "rainbows"
secondInnerFunction() ; // defines innerInnerFunction
innerInnerFunction() ; // returns "clouds"
var cnt1 = 0;
function initOctoView(){
var newcnt1 = printAdsBox1(cnt1, imgPerBox1); // first time on first load
var totalBoxes8 = setInterval(function() {
newcnt1 = printAdsBox1(newcnt1, imgPerBox1); // all 5 sec
}, 5000);
}
This function get called by this:
if($('.octoView').length > 0){
initOctoView();
}
And works fine so far.
Later on I have:
$(document).on('click', 'a.windowXL', function () {
window.clearInterval(totalBoxes8);
}
But this returns that totalBoxes8 is not defined.
What is my mistake? Please advice!
You declare totalBoxes8 with var inside function - totalBoxes8 is local variable accesable in this function only. You may make it global:
var cnt1 = 0;
var totalBoxes8;
function initOctoView(){
var newcnt1 = printAdsBox1(cnt1, imgPerBox1); // first time on first load
totalBoxes8 = setInterval(function() {
newcnt1 = printAdsBox1(newcnt1, imgPerBox1); // all 5 sec
}, 5000);
}
Try this;
$(function(){
var cnt1 = 0, totalBoxes8 ;
function initOctoView(){
var newcnt1 = printAdsBox1(cnt1, imgPerBox1); // first time on first load
totalBoxes8 = setInterval(function() {
newcnt1 = printAdsBox1(newcnt1, imgPerBox1); // all 5 sec
}, 5000);
}
$(document).on('click', 'a.windowXL', function () {
window.clearInterval(totalBoxes8);
}
});
totalBoxes8 is undefined because it is declared locally within the scope of the function initCotoView(), and is thus unavailable to the global scope
you can declare a global from within the function by explicitly attaching it to the global window object. Something like:
function foo() {
window.myVar = 1; // declares a global
}
foo(); // call the function to actually make the declaration
console.log(window.myVar); // the variable is accessible globally