I know how to access the below member function when it's written like this:
var blady_blah=
{
some_member_function: function ()
{
}
}
I access it from outside doing blady_blah.some_member_function()
But how do I access the member function when it's written like this:
(function() {
some_member_function: function ()
{
}
})();
Braces, { }, are used to define both object literals and function bodies. The difference is:
var name = {}; // Object literal
Which you may also see written as
var name = {
};
That's just the same but with some space in between so it's still an object literal, and unfortunately it looks very similar to:
var name = function () { // Function body
};
An object can have members:
var name = {
member: "string"
};
Whereas a function cannot; a function has statements:
var name = function () {
do_something();
var result = do_something_else();
};
You can't write
var name = function () {
member: "string"
};
Because you've mixed the two uses of { } together.
A variable can be defined within a function, but it can't be seen outside the function - it's within the function scope:
var name = function () {
var something_useful = string;
};
The second example is a closure (it just happens to have a syntax error inside). Minus the bad syntax, your self-evaluating anonymous function looks like this:
(function() {
})();
If you'd like, you can define functions inside this that will be invisible to the outside world. This is useful if you're interested in maintaining a clean global namespace, for example with library code.
(function() {
function utilityFunctionFoo() {
}
function utilityFunctionBar() {
}
})();
Of course, if you'd like to call any of these functions from the outside world, you're out of luck. Or are you? Actually, there's another way to define a function:
var foo = function() {
}
That's exactly the same as writing:
function foo() {
}
...Except that when written in the second style, you can actually omit the var keyword and create a global variable! Bringing it all together:
(function() {
publicData = "stuff accessible from outside anonymous function";
var privateData = "stuff that stays inside anonymous function";
function utilityFunctionFoo() {
}
function utilityFunctionBar() {
}
usefulFunctionExport = function() {
utilityFunctionFoo();
utilityFunctionBar();
}
})();
usefulFunctionExport();
You can't access it after the function it's in terminates. It's a local variable that goes out of scope when its parent function ends.
You should make the main function be a constructor so that it returns a new instance of a class (you could name it Blahdy_blah) with the member function as one of its properties.
Look up constructors, their return values, and accessing member variables.
If you want to execute the function you need to return an object that exposes the function.
var LIB = (function() {
var fn = {
member_function : function(){}
};
return fn;
})();
and to call
LIB.member_function();
(function() {
blady_blah.some_member_function();
})();
If you need to add stuff into it you would write it like this.
(function() {
blady_blah.some_member_function(function(){
// Do stuff...
});
})();
Related
const ui = (function() {
let ourvar = 'iffe called!!!';
return {
func_1: function() {
console.log(ourvar)
}
}
})();
console.log(ui.func_1())
Here notice the function inside the return. Its named func_1:function(){} instead of the normal conventional way of naming functions which is function func_1(){}. Why is it named here so?
Why wouldn't normal function declaration method work here?
Thanks
The IIFE is returning an object. An object contains key value pairs. So in your code func_1 is the key that has the value of a function. All these are valid ways to declare it:
return {
xyz: function() {}
}
Or
return {
xyz: function abc() {}
}
Or you can declare the function using normal syntax and refer it inside the object literal like this:
function abc() {}
return {
xyz: abc
}
In ES6 you can use even this syntax:
return {
xyz() {}
}
You can't use the normal function declaration syntax inside object literals like:
return {
function xyz() {}
}
This makes no sense. This is like:
return {
var a = 10
}
which also makes no sense inside an object literal.
You could use a function declaration and then reference it in the object literal.
Using a function expression is shorter.
const ui = (function() {
let ourvar = 'iffe called!!!';
function func_1() {
console.log(ourvar)
}
return {
func_1
};
})();
console.log(ui.func_1())
In javascript, functions are first class, meaning that they can be treated like any other variable.
In your example, you could do this instead:
const func_1 = function() {
console.log(ourvar);
}
return {
func_1: func_1
}
In javascript you can also shorten this to just:
return {
func_1
}
Purpose: I need to call sub function within main one;
Function declaration:
var MainFunction = function () {
function NestedFunc1(){
console.warn("NestedFunc1");
};
function NestedFunc2(){
console.warn("NestedFunc2");
};
}
Functions call:
MainFunction.NestedFunc1();
MainFunction.NestedFunc2();
What am I doing wrong?
10x;
you can make it public via a property then
function MainFunction () {
this.nestedFunc1 = function(){
console.warn("NestedFunc1");
};
this.nestedFunc2 = function(){
console.warn("NestedFunc2");
};
}
now you can invoke this function outside by doing
var malObj = new MainFunction();
malObj.nestedFunc1();
However, if you want to still invoke it like MainFunction.NestedFunc1() then make it
var MainFunction = {
NestedFunc1:function (){
console.warn("NestedFunc1");
},
NestedFunc2:function (){
console.warn("NestedFunc2");
}
}
The issue is that both of those functions are isolated within a function scope. Think of them as private functions.
One (of many) solutions could be to define MainFunction as a plain ol' object that has some functions as attributes:
var MainFunction = {
NestedFunction1: function () { .. },
NestedFunction2: function () { .. }
};
Notice that a comma is needed to separate the functions because of the way we are defining them. You then just call
MainFunction.NestedFunction1();
Also note that this pattern is fine as long as you don't wish to have other "private" functions inside that object.
Seems like I can only create a global variable for this to work but here is what would be ideal. I would like to pass a variable to an object which has keys that reference functions. In the function I am referencing I would like to set either that variable or one that was defined within the function that called it and pass it back:
jsfiddle
var methodHandler = {
'a-key': function () {
aVariable = document.getElementById('a-container');
}
}
function sample() {
var aVariable;
methodHandler['a-key']();
console.log(aVariable);
}
sample();
Because of scoping, you can't really do it that way. However, you could restructure it like this and get a similar result:
var methodHandler = {
'a-key': function () {
return document.getElementById('a-container');
}
}
function sample() {
var aVariable = methodHandler['a-key']();
console.log(aVariable);
}
sample();
You should use the this element. The this element, when referenced inside a function of the object, represents the object itself, so doing this.foo = 1 will actually create a property called foo with the value of 1 in your object.
Here is the correct form of the code:
var methodHandler = {
'a-key': function () {
this.aVariable = document.getElementById('a-container');
return this.aVariable;
}
}
function sample() {
// You can do this:
methodHandler['a-key']();
console.log(methodHandler['aVariable']);
// Or you can do this instead:
console.log(methodHandler['a-key']());
}
sample();
When you call methodHandler['a-key'](), the property aVariable will be set in your object, so if you log the object you'll see this:
console.log(methodHandler);
// Object {a-key: function, aVariable: div#a-container}
I always have difficulty grasping new concepts without seeing a real, basic, working example of what I am reading about. While I like the other explanation on stackoverflow, I'd really like to see a very basic example showing the difference between methods and functions in JavaScript that I can quickly run to learn more.
A method is just a function that is a property of an object. It's not a different type of object in javascript, but rather method is just the descriptive name given to a function that is defined as a property of an object.
var myObj = {};
myObj.go = function() {alert("hi");}
myObj.go();
In this example, go is a method on the myObj object.
When a method is called as in the above example myObj.go(), then the value of the this pointer is set to the object that was involved in the invocation of the method (in this case myObj).
Since global functions are also implicitly properties on the window object, one could say that global functions are also methods on the window object, but you do not need the window designation in order to call them.
Local functions like inner() in this function are just functions and not methods as they are not attached to a particular object:
function main() {
function inner() {
alert("hi");
}
inner();
}
This is a function and a function call:
function myFunction(){
alert("This is a function!");
}
myFunction();
This, on the other end, is a method call, because it is a member function of an object.
message.toUpperCase();
Here's the full code to create a class/methods and a call:
function Circle(x,y,r) {
this.xcoord = x;
this.ycoord = y;
this.radius = r;
}
Circle.prototype.retArea = function () {
return ( Math.PI * this.radius * this.radius );
};
var aCircle = new Circle(1,2,3);
var a = aCircle.retArea();
example:
function:
var f1 = function fBase() { ... }
function f2() { ... }
var f3 = function() { ... }
f1()
f2()
f3()
method:
var c = function oBase() {
this.method1 = function() { ... };
}
c.prototype.method2 = function() { ... }
var o = new c()
o.method1()
o.method2()
method json:
var o = { method1: function() { ... } }
o.method2 = function() { ... }
o.method1()
o.method2()
A function is a type which can be used to define a piece of code that can be executed by using call ("()") operator and may return data to the caller.
e.g.
define
function sayHello(){
return "Hello";
}
use
var result = sayHello();
Now, result will contian "Hello".
A method is a function that is defined inside an object and accessible through a property. For example, slice is function defined over all string instances
e.g.
define
var obj = {
sayHello : function(){
return "Hello";
}
};
you can also define methods outside the object definition
var obj = {};
obj.sayHello = function(){
return "Hello";
};
use
var result = obj.sayHello();
We use methods in object oriented programming.
Refer:
Functions at MDN
Objects at MDN
why doesn't this work as expected. (see expected comment)
var Module = function () {
var public_instance_var;
function doStuff () {
Module.doOtherStuff();
console.log(public_instance_var); // expected: true, but logs undefined
};
function doOtherStuff() {
public_instance_var = true;
};
return {
public_instance_var: instance_var,
doStuff: doStuff,
doOtherStuff: doOtherStuff
}
}();
Module.doStuff();
Update: Fixed accordingly to a few of jAndy suggestions
Multiple errors here:
You don't return DoStuff as module interface
instance_var is not declared, probably meant public_instance_var
doOtherStuff is never assigned to Module, just call it like doOtherStuff();
Fixed code:
var Module = function () {
var public_instance_var;
function doStuff() {
doOtherStuff();
console.log(public_instance_var); // expected: true, but logs undefined
};
function doOtherStuff() {
public_instance_var = true;
};
return {
doStuff: doStuff,
public_instance_var: public_instance_var
}
}();
Module.doStuff();
change your code like so
var Module = function () {
var public_instance_var;
function doStuff () {
doOtherStuff();
console.log("var is ", public_instance_var); // expected: true, but logs undefined
};
function doOtherStuff() {
public_instance_var = true;
};
return {
public_instance_var: public_instance_var,
doStuff : doStuff
}
}();
Module.doStuff();
you have to return doStuff() function (otherwise outside it will be undefined) and public_instance_var instead of instance_var
you need to execute doOtherStuff() without prefixing Module.
What this code does is, simply put: create and run a function and assign its return value to a variable: Module. The return value is an object with 1 property: public_instance_var, that points to the variable instance_var, or (after correcting the typo: public_instance_var). This variable was declared, but not instantiated. Therefore the return value looks like this:
Module.public_instance_var = undefined
The very last line Module.doStuff(); won't work one bit: Module is an object that has no methods. The functions you declared are garbage collected when the anonymous function returns. If you want access to those functions, you'll need to include them in the return statement. Read up on closures, Object constructors and design patterns in general, but I'd say the code you're after will look something like this:
var Module = (function()
var public_instance_var;
function doStuff () {
this.doOtherStuff();
console.log(public_instance_var); // expected: true, but logs undefined
};
function doOtherStuff() {
public_instance_var = true;
};
return {
public_instance_var: public_instance_var,
doStuff: doStuff,
doOtherStuff: doOtherStuff
};
})();
Of course, this way your variable public_instance_var is a public property, so my guess would be what you're really trying to do is simulate a private properties and methods. In which case you might end up with code similar to this:
var Module = (function()
{
var public_instance_var;
return {
//public_instance_var: public_instance_var, remove this line
//the closure will preserve access to the variable
doStuff: function ()
{
this.doOtherStuff();//this, you're referencing the object's property
console.log('here I am');
},
doOtherStuff: function ()
{
public_instance_var = true;
//this won't work anymore:
//this.public_instance_var = true;
};
}
})();
Module.doStuff() now logs here I am, but the doOtherStuff is now a public method, too. Here's how you might choose to solve the issue:
var Module = (function()
{
var public_instance_var;
function doOtherStuff ()
{
public_instance_var = true;
};
return {
//public_instance_var: public_instance_var, remove this line
//the closure will preserve access to the variable
doStuff: function ()
{
doOtherStuff();//don't use this here, but the reference to the function exists thanks to closure
console.log('here I am');
console.log(public_instance_var);//logs true
}
};
})();
These are just a few of the very powerful things you can do with closures and functions returning objects. Just read a couple of articles, like this one, there are better ones out there. Google the term power constructors