I do this
function myFunction() {
var myVar = "I think I am encapsulated";
function getMyVar() {
return myVar;
}
}
var myProperty = myFunction;
myProperty.getMyVar(); // tells me myProperty.getMyVar is not a function.
and
function myFunction() {
var myVar = "I think I am encapsulated";
function getMyVar() {
return myVar;
}
}
var myProperty = myFunction();
myProperty.getMyVar(); // tells me myProperty is undefined
and even
function MyFunction() {
var myVar = "I think I am encapsulated";
function getMyVar() {
return myVar;
}
}
var myProperty = new MyFunction();
myProperty.getMyVar(); // tells me myProperty.getMyVar is not a function.
and in all three cases I get problems. I have included the problem as in line comment in all three sections. Now, before someone tells me to just use a closure, I am not trying to understand closures, I am trying to understand exactly what happens with inner functions.
If you can explain above, I would grateful. Because it is counter intuitive to me.
Thanks
What you did is just define a function inside myFunction, creating a closure ...
To remedy the implementation, make getMyVar an instance member:
function myFunction() {
var myVar = "I think I am encapsulated";
this.getMyVar = function () {
return myVar;
}
}
You aren't exposing the getMyVar function.
You want:
function myFunction() {
var myVar = "I think I am encapsulated";
this.getMyVar = function() {
return myVar;
}
}
However, myVar is also locally scoped to the function execution... and the funciton hasn't been executed.
The last lines need to be
(new myFunction()).getMyVar();
EDIT: Though perhaps all you're looking for is pseudo-namespacing? In which case you can do:
var myObject = {
myProperty: "value",
myFunction: function() { }
}
Or, more likely you're trying to make myVar act like a private member, in which case you can do:
var myObject = function() {
var myVar = "I think I am encapsulated";
return {
getMyVar: function() {
return myVar;
}
}
}(); //self-executing function
Related
I'm pretty sure this is n00b question, but I'm completely new to javascript. I'm wondering why this code only prints "hello" but when I comment out the first function, that's when I get the second function to print the other two words. How does this make sense?
var function1 = createFunction();
function createFunction()
{
console.log("hello");
}
function1();
function createFunctionPrinter(word)
{
console.log(word);
}
var printSample = createFunctionPrinter('sample');
var printNoo = createFunctionPrinter('noo');
printSample(); //should console.log('sample');
printNoo(); //should console.log('noo');
function1 is the return value of calling createFunction which is undefined because createFunction has no return statement.
undefined is not a function, so calling function1() raises an exception and execution halts.
If you want to refer to an method, you should leave the (), as the function call return undefined.
See this example
function createFunction()
{
console.log("hello");
}
var function1 = createFunction;
function1();
function createFunctionPrinter(word)
{
console.log(word);
}
var printSample = createFunctionPrinter;
var printNoo = createFunctionPrinter;
printSample('sample'); //should console.log('sample');
printNoo('noo'); //should console.log('noo');
Fixing function1 and createFunction() should be easy, provided the fact no arguments are needed for this. Simply set var function1 = createFunction without () and you it will effectively make function1 call createFunction as if that was the function's name.
createFunctionPrinter() is a bit different. My preferred approach is the use of a prototype, which will take an argument (word) when called, and then when you call its print() method, it will essentially print your text. The assignment of printSample and printNoo is similar, but you have to use the new keyword. Finally, to make the functions print, use something like printSample.print().
function createFunction() {
console.log("hello");
}
function createFunctionPrinter(word) {
this.word = word;
this.print = function() {
console.log(word);
}
}
var function1 = createFunction;
function1();
var printSample = new createFunctionPrinter('sample');
var printNoo = new createFunctionPrinter('noo');
printSample.print();
printNoo.print();
P.S.: This might not the intended use of prototypes, but I believe it will make your life easier to use them in this case.
var function1 = createFunction();
function createFunction()
{
// return a function that prints a message
return function() {
console.log("hello");
}
}
function1();
This is my IIFE function
var test = function(){
console.log('fire');
}();
It invokes at start. But how do I call this again?
var fireTestFn = function(){
test();
}
fireTestFn(); // test() is not a function
JSbin https://jsbin.com/cesuzimogu/edit?js,console
You could return test from inside using a named function expression.
var test = function fn(){
console.log('fire');
return fn;
}();
The result of the IIFE will be assigned to test, which is obviously not a function, because you're not returning a function from the IFEE (or anything for that matter). Keep it simple; what you want is a named function you can call anytime as many times as you want:
function test() {
console.log('fire');
}
test(); // call as often as you want
Something like this will work
var myNamespace = {};
(function(ns) {
ns.test = function(){
console.log('fire');
};
/*ns.myOtherFunction = function(var1) { }*/
})(myNamespace);
var fireTestFn = function(){
myNamespace.test();
};
fireTestFn();
See example here: https://jsbin.com/helumoveqe/edit?js,console
As the error says
test() is not a function
When you self-invoked the function, the result was stored into test.
In order to be able to use test as a function and call repeatedly elsewhere, do not self-invoke
var test = function(){
console.log('fire');
};
or have the function return an inner function
var test = function () {
return function () {
console.log('fire');
}
};
I am hoping that someone can help me figure out how to do this correctly, rather than just "make it work."
I am trying to use an object inside a closure, and having scope issues:
var Why = function() {
this.foo = 'bar';
}
Why.prototype.explain = function () {
alert(this.foo);
}
Why.prototype.doIt = function () {
this.explain();
}
(function() {
document.addEventListener("DOMContentLoaded", function(event) {
var why = new Why();
why.doIt();
});
})();
And I get in console:
Uncaught TypeError: this.explain is not a function
I could use
Why.prototype.explain.call();
but that just seems wrong, and when I actually do that... this.foo is undefined anyway, so it's obviously not the right approach.
If I remove the self calling function as follows...
var Why = function() {
this.foo = 'bar';
}
Why.prototype.explain = function () {
console.log(this.foo);
}
Why.prototype.doIt = function () {
// Why.prototype.explain.call();
this.explain();
}
// (function() {
document.addEventListener("DOMContentLoaded", function(event) {
var why = new Why();
why.doIt();
});
// })();
then it works of course, but:
what am I missing and where/how can I learn it?
Thanks in advance.
Your code is parsed as
Why.prototype.doIt = function () { ... }(function() { ... });
You're calling the function you want to assign to the prototype, then assigning its return value. Since it returns undefined, Why.prototype.doIt doesn't exist.
You need a semicolon.
I have the following piece of code:
function initValidation()
{
// irrelevant code here
function validate(_block){
// code here
}
}
Is there any way I can call the validate() function outside the initValidation() function? I've tried calling validate() but I think it's only visible inside the parent function.
function initValidation()
{
// irrelevant code here
function validate(_block){
console.log( "test", _block );
}
initValidation.validate = validate;
}
initValidation();
initValidation.validate( "hello" );
//test hello
Hope that you are looking for something like this
function initValidation()
{
// irrelevant code here
this.validate = function(_block){
// code here
}
}
var fCall = new initValidation()
fCall.validate(param);
This will work.
Hope this addresses your problem.
You can call validate from within initValidation. Like this.
function initValidation()
{
// irrelevant code here
function validate(_block){
// code here
}
return validate(someVar);
}
validate is not visible to anything outside of initValidation because of its scope.
Edit: Here's my suggestion of a solution.
(function() {
function validate(_block){
// code here
}
function initValidation()
{
// irrelevant code here
return validate(someVar);
}
function otherFunctions() {
// ...
}
// initValidation = function
}());
// initValidation = undefined
All of your functions will be hidden to anything outside the function wrapper but can all see each other.
This invocation will return function statement, which is function validate.
So you can invoke directly after the first invocation.
function initValidation() {
// irrelevant code here
return function validate(_block) {
// code here
}
}
initValidation()();
I know this is an old post but if you wish to create a set of instances that you wish to work with that reuse the code you could do something like this:
"use strict";
// this is derived from several posts here on SO and ultimately John Resig
function makeClassStrict() {
var isInternal, instance;
var constructor = function(args) {
if (this instanceof constructor) {
if (typeof this.init == "function") {
this.init.apply(this, isInternal ? args : arguments);
}
} else {
isInternal = true;
instance = new constructor(arguments);
isInternal = false;
return instance;
}
};
return constructor;
}
var MyClass = makeClassStrict();// create "class"
MyClass.prototype.init = function(employeeName, isWorking) {
var defaultName = 'notbob';
this.name = employeeName ? employeeName : defaultName;
this.working = !!isWorking;
this.internalValidate = function() {
return {
"check": this.working,
"who": this.name
};
};
};
MyClass.prototype.getName = function() {
return this.name
};
MyClass.prototype.protoValidate = function() {
return {
"check": this.working,
"who": this.name
};
};
var instanceBob = MyClass("Bob", true);// create instance
var instanceFred = MyClass("Fred", false);// create instance
var mything = instanceFred.internalValidate();// call instance function
console.log(mything.check + ":" + mything.who);
var myBobthing = instanceBob.protoValidate();
console.log(myBobthing.check + ":" + myBobthing.who);
I know this thread's been here for quite some time but I thought I'd also leave my 0.02$ on how to call inner functions from outside their scope (might benefit somebody).
Note that in any place, a better design decision should be taken into consideration rather than some hackish workaround which will bite you back later.
How about using function expressions instead of function statements and making use of the global scope.
var innerFn;
function outerFn() {
innerFn = function(number) {
return number ** 2;
}
}
outerFn();
console.log(innerFn(5));
// if there's more complex code around and you could write this defensively
if (typeof innerFn !== 'undefined') {
console.log(`we are squaring the number 5 and the result is: ${innerFn(5)}`);
} else {
console.log('function is undefined');
}
Or, you can make use of closures:
function outer() {
// initialize some parameters, do a bunch of stuff
let x = 5, y = 10;
function inner() {
// keeps references alive to all arguments and parameters in all scopes it references
return `The arithmetic mean of the 2 numbers is: ${(x + y) / 2}`;
}
return inner;
}
innerFn = outer(); // get a reference to the inner function which you can call from outside
console.log(innerFn());
Create a variable outside the parent function, then in the parent function store your required function in the variable.
Var Store;
Function blah() {
Function needed() {
#
}
Store = needed;
}
As a minor variation of Esailija's answer, I did this:
function createTree(somearg) {
function validate(_block) {
console.log( "test", _block );
}
if (somearg==="validate") { return validate; } // for addNodes
// normal invocation code here
validate(somearg);
}
function addNodes() {
const validate = createTree("validate");
//...
validate( "hello" );
}
createTree("create");
addNodes();
//validate("illegal");
so validate() is now perfectly shared between createTree() and addNodes(), and perfectly invisible to the outside world.
Should work.
function initValudation() {
validate();
function validate() {
}
}
Function definition:
function initValidation() {
// code here
function validate(_block){
// code here
console.log(_block);
}
return validate;
}
Call it as below:
initValidation()("hello");
function initValidation()
{
function validate(_block){
console.log(_block)
// code here
}
// you have to call nested function
validate("Its Work")
}
// call initValidation function
initValidation()
A JavaScript newbie here. I have this following code:
function testObject(elem) {
this.test = "hi";
this.val = elem;
console.log(this.test+this.val);
echo();
function echo () {
console.log(this.test+this.val);
}
}
var obj = new testObject("hello");
When it is run, I expect "hihello" to be outputted twice in the console. Instead it outputs as expected the first time but returns NaN the second time.
I'm sure I'm missing something here. I thought that the internal function can access the vars held outside. Can someone please guide me? I'm more of a functional UI developer and don't have much experience with OO code.
Thanks!
The problem is that inside echo the this value points to the global object, and this.test and this.val (which are referring to window.test and window.val) are undefined.
You can set the this value of echo by invoking it like:
echo.call(this);
That happens because you were invoking the function by echo();, then the this value is implicitly set to the global object.
Give a look to this question to learn how the this value works.
Edit: For being able to calling just echo(); you should persist the this value from the outer function context, there are a lot of ways to do it, for example:
//...
var instance = this; // save the outer `this` value
function echo (){
console.log(instance.test+instance.val); // use it
}
echo();
//...
Or
//...
var echo = (function (instance) {
return function () {
console.log(instance.test+instance.val);
};
})(this); // pass the outer `this` value
echo();
//...
You could also do this:
function testObject(elem) {
this.test = "hi";
this.val = elem;
console.log(this.test+this.val);
this.echo = function () {
console.log(this.test+this.val);
}
this.echo();
}
var obj = new testObject("hello");
​Whenever you call this.echo() or obj.echo(), this will be bound to the object invoking the function.
Personally, I find it elegant to declare class methods like this:
function testObject(elem) {
this.test = "hi";
this.val = elem;
this.echo();
}
testObject.prototype = {
echo: function () {
console.log(this.test + this.val);
}
}
var obj = new testObject("hello");