I've used this ability previously but for some reason, it isn't working and is giving the error below. I am not sure why and it is probably something obviously wrong that I am not seeing.
TypeError: (intermediate value).inside is not a function
Caller is called and runs a new outside function which specifically targets the inside function to run alone leaving the rest of the outside function none of the wiser about inner running.
function caller() {
new outside().inside();
}
(function outside() {
function inside() {...}
})();
caller();
Preferably outside() would be a self invoking function, but I don't think that is even possible.
A function declared inside another function creates a local variable in the scope of that function, it does not create a property on the return value of the function.
If you want the latter, then you have to create it explicitly.
Also note, since you are using the new keyword, that constructor functions are expected to be named with an initial capital letter.
function caller() {
new Outside().inside();
}
function Outside() {
function inside() {
console.log("Inside");
}
this.inside = inside;
}
caller();
Related
In my knockout.js project I wrote some self invoking functions like this:
var addMarkers = function () {
ko.utils.arrayForEach(self.sectionList(), function (sectionItem) {
ko.utils.arrayForEach(sectionItem.placeList(), function (placeItem) {
placeItem.marker.addListener('click', function () {
map.panTo(placeItem.marker.getPosition());
});
});
});
}();
The function works without problems, however in JSLint the "var addMarkers" was highlighted as unused variable. That makes me wonder if I should the function like this, or just make anonymous because it is a better practice?:
function addMarkers (){ code to be executed };
Assigning the result of a self-executing function is often useful. In particular, I like to define my main viewmodel this way, because
I don't need a prototype for my viewmodel
I'm not likely to need more than one instance of a viewmodel
The reason you would use a self-executing function is that you need a local scope for whatever you're doing, to isolate it from surrounding scope. The reason you would assign a variable from it is that you want it to return a value you will use later. In your example, neither of these is true.
Being new to JavaScript, I came across a feature in JavaScript where we can write function inside a function which looks cool, but I didn't understand any practical use of it and also how to call the child function?
var parent = "global";
function Parent() {
alert(parent);
function child() {
alert("i am child");
}
}
So, in the above example function parent embeds child function, but I'm not sure on the following 2 questions:
What's the practical use of such syntax / functionality?
How to call child function?
I'm not sure anyone actually gave you the simple answer for what you asked. Defining the child() function inside the Parent() function is just defining a "local" function whose scope is limited to only within the Parent() function's code. It's analogous to a local variable that only exists inside a function.
So, when you have this:
function Parent() {
function child() {
alert("i am child");
}
}
You've created a new function named child which can be called from the code inside of the Parent() function like this:
function Parent() {
function child() {
alert("i am child");
}
child();
}
This function is truly local to within the Parent() function and cannot be called from anywhere else. So, this will not work:
function Parent() {
function child() {
alert("i am child");
}
}
child(); // this function will be undefined
The simplest reason for defining a function this way is just to contain where it can be used and to reduce potential name conflicts. If you couldn't define local functions like this, then all functions would have to be global (or methods on some object) and you'd potentially have a giant set of possible name collisions. This way, you can define functions within a scope that they apply to and they don't potentially collide with any other functions defined similarly within their own scope.
When you get into more advanced uses of javascript, the child() function also has access to all of the variables of its parent. So, you can do this:
function Parent() {
var msg = "Hello!";
function child() {
alert(msg);
}
child(); // will put up an alert that says "Hello!"
}
This allows those local functions to share all the variables from the parent context without having to pass them all to the function. This can be particularly useful when using callbacks because it allows the callbacks to have access to a whole context even though the callback was called by some other code. Here's a simple example of a callback having access to some useful state.
function blink(elem, numTimes, duration) {
var timer, visible = true;
// callback function that is called
function handleInterval() {
// toggle visible state
var val = visible ? "hidden" : "visible";
elem.style.visibility = val;
visible = !visible;
--numTimes;
if (numTimes <= 0) {
clearInterval(timer);
}
}
timer = setInterval(handleInterval, duration);
}
Here you notice that the handleInterval() function has access to not only the local variables from the blink() function, but also the arguments passed to it. This allows us to keep some state going for the setInterval() without using global variables. There's also a more advanced thing going on here called a closure. Closure's can be a bit complicated of a concept, but understanding a couple uses is generally fairly simple.
In this case, the blink() function gets called. It's job is to create an interval timer that, when called will toggle the visibility state of the passed in element. After a certain number of blinks, it will stop the interval timer. But, all the blink function does is call the setInterval() function to schedule the interval timer. It then immediately finishes and is done executing. But, because the setInterval() function has been schedule and it has been passed a reference to the handleInterval() function and that function is in the scope of the blink() function, then all the local variables of the blink() function are "kept alive" and operating even though the blink() function has already finished executing. In fact, these variables will be uniquely kept alive until the timer is stopped and nothing can call handleInterval() any more. If javascript didn't have this capability, then a number of variables in this simple solution would have to be declared as global variables or properties of some object that persists for the duration of this activity. This technique allows the code to much cleaner and self-contained.
Local functions don't have to be named. They can also be anonymous. A more typical way to implement blink() would be like this using an inline anonymous function callback instead of giving it a name:
function blink(elem, numTimes, duration) {
var timer, visible = true;
timer = setInterval(function() {
// toggle visible state
var val = visible ? "hidden" : "visible";
elem.style.visibility = val;
visible = !visible;
--numTimes;
if (numTimes <= 0) {
clearInterval(timer);
}
}, duration);
}
If you're only ever calling this function in one place, then it doesn't really need to be declared separately and given a name. It can, instead be defined inline like this as an anonymous function.
This concept is mainly used in OOJS (Object Oriented JavaScript). Consider the example below:
var Employee=function(ename,eage){
var _name=ename;
var _age=eage;
this.getName=function(){return _name;};
this.getAge=function(){return _age;};
};
var e1=new Employee("Xyz",45);
var e2=new Employee("Abc",23);
e1.getName(); //output=Xyz
e1.getAge(); // output=45
and so on ...
It's a closure which is a way to control scope in JavaScript. Anything defined inside the closure is not visible outside the closure. With a small modification to your function you can call it like so:
var parent = "global";
function Parent(a) {
alert(parent);
function child(b) {
alert(a + b); //child can see both a and b
}
return child;
}
parent(1)(2);
This can be used to implement currying which is explained here Javascript curry - what are the practical applications?
I had this code:
Javascript
(function() {
function read() {...}
})();
HTML
<body onload="read()">
Console said, read is undefined.
After deleting the IIFE it worked, why?
Thanks. :)
Here's a long but satisfying explanation about JavaScript scope and closures.
Since you declare read inside a function, it is local to that function.
Anything you declare inside a function will be local to it.
You can explicitly put it into global scope by assigning it as a property to window:
(function() {
function read() {...}
window.read = read;
})();
Writing
(function() {
function read() { ... }
})();
Is very nearly the same thing as writing
(function() {
var read = function() { ... } //this is different, but not significantly so
//for purposes of teaching this point
})();
and I think you should already understand why a var declared inside a function is not available outside of that function's scope.
The behavior of a function definition (function read() { ... }) is slightly different from the behavior of assigning a function expression to a variable (var read = function() { ... };) in terms of when the name of the function and the function become associated, but the two are otherwise identical.
Because it isn't defined globally. It's only been defined within the scope of that immediately invoked function. To make it global either use this:
function read() {...}
(function() {
...
})();
Or this:
(function() {
window.read = function() {...}
})();
Or better yet, just bind the onload event within the immediately invoked function:
(function() {
function read() {...}
window.onload = read;
})();
In this case the definition of read is inside the IIFE. This limits the scope of the function to the IIFE and any child functions inside of it. The handler for onload is executed in the global scope and hence doesn't have access to read
So I was getting the following error:
TypeError: parentRef.parentFunction() is not a function
in my callee.
My callee looked sort of like this
function callee(parentRef){
function subRoutine(){
//stuff
parentRef.parentFunction(params);
}
}
And the caller looked like this:
function caller(){
refToCallee = new callee(this);
refToCallee.subRoutine();
parentFunction(prms){
//other stuff
}
}
Then I realized that I had seen code that changed the caller to have the following line when defining parentFunction
this.parentFunction = function(){ etc.}
What is the thiskeyword doing here. Is it a namespacing thing? More specifically why does my first definition without using the this.funcName syntax not work?
When you define a function like parentFunction inside another function like caller, there are 3 ways of doing it.
function parentFunction() { ... }
var parentFunction = function() { ... };
this.parentFunction = function() { ... };
The first declares a function inside the scope of caller. It is only usable inside caller.
The second declares a local variable that happens to be a function, it is also only callable inside caller.
The third declares a property on the caller object that happens to be a function. Anyone with a reference to a caller object (like in your example) can call it. This is why the this.parentFunction is needed for callee to be able to use it.
What you have in your original example,
parentFunction(prms) { ... }
is not proper javascript. It does not declare a variable or a function, nor does it execute any code.
It appears you want a callback like this:
function callee(callback){
//stuff
callback(params);
}
function caller(){
callee(callback);
function callback(prms){
//other stuff
}
}
Question inside the description
function Parent(){
this.alertParent(){
alert("Parent alert");
}
function child(){
// how can I call to this.alertParent() from here without passing any
// parameters?
}
}
The title of your question is confusing. The informal term "parent" function is rather used for the calling function.
In your case, you have two functions inside a constructor function and you just want to call one from the other. Specifically, you want to call a "public" method from a "private" method (I put these terms in quotes since JavaScript does not support visibility and these are workaround to achieve the same).
Just keep a reference to the current instance:
function Parent(){
var self = this;
this.alertParent = function() {
alert("Parent alert");
}
function child() {
self.alertParent();
}
}
child closes over all variables in the context it is defined, so it as access to self. this of course changes [MDN].
Instead of creating a closure, you can also pass the instance explicitly to child, using either .call() [MDN] or .apply() [MDN].
So your function definition stays
function child() {
this.alertParent();
}
and when you call the function, you call it, e.g. with child.call(this) if you know that this refers to your instance (instead of this it can be any other variable).
Your code has syntax error. Maybe you means this:
function Parent(){
this.alertParent = function () {
alert("Parent alert");
};
this.child = function () {
this.alertParent();
}
}