Is there a way to declare functions in constructor? - javascript

First of all, I recognize there are like 100+ threads on method.this vs var method, etc. That is not what I am asking. I know the differences. I am confused of function expressions VS function declarations in the context of creating objects using a constructor.
What I wanted to know is this: How come function declarations never appear in constructors, but function expressions do? Whenever I declare a function rather than use an expression it is not accessible in the object once initiated; why is this?
I think it is because either it is local (aka private) and thus inaccessible, or when creating objects, if the constructor does not see the function prefixed with 'this', 'var', or 'constructor.prototype', it skips it.

How come function declarations never appear in constructors, but function expressions do?
They do
Whenever I declare a function rather than use an expression it is not accessible in the object once initiated; why is this?
You must be doing it wrong.
function Thing() {
function go() {
alert('Hello');
}
this.foo = 1;
this.bar = function () {
go();
}
}
var x = new Thing();
x.bar();
I think it is because either it is local (aka private) and thus inaccessible
Function declarations are locally scoped. That doesn't stop you assigning them to a wider scope, to an object property or using them within the scope they are declared within.

How come function declarations never appear in constructors, but function expressions do?
They do. You could easily replace every function expression with an equivalent function declaration.
Whenever I declare a function rather than use an expression it is not accessible in the object once initiated; why is this?
Because function declaration declare a function in the current scope, just as var declares a variable. See also Javascript: Do I need to put this.var for every variable in an object? for the difference between variables and properties.
if the constructor does not see the function prefixed with 'this', 'var', or 'constructor.prototype', it skips it.
Nope. It's not about "being seen prefixed with". You are writing the code, and the engine doesn't know what it is executing. A function expression by itself is nothing but an expression, it gathers a meaning when you do assign it somewhere. When you assign it to a property of the current instance (this), it becomes a method for example. The same can be done with a function declaration:
function Constructor() {
// creating local identifiers:
var variable = function expression(){ };
function declaration() { };
// exporting properties:
this.method1 = variable;
this.method2 = declaration;
// or without the local variable:
this.method3 = function expression() { };
}

Related

Javascript: Global Context and Function Context Declarations

I have noticed something while playing around which has sparked a quick question.
When code is executed in the global/window context, any function declarations get added as methods to the window object.
But when I am in the context of another object, writing a function declaration does not add the method to my objects methods.
function functionInGlobalCtx() { // This will be added as a function to the window object
// code...
}
var myObject = {};
myObject.myObjectFunction = function () {
var $this = this; // The context here is the 'myObject' object
function functionHopefullyInMyObjectCtx() {
// code...
}
}
myObject.myObjectFunction();
Why does the function declaration exist as part of the window object but not the one for the object?
Is this simply 'how JavaScript works' (special rules apply to the global context?) or am I missing something?
Thanks.
Its actually understandable. Function is object. Myobject and myobjectfunction are two different objects. So are 'this' and function itself.
In your example, you define the hopefullyfunction in myobjfunction, not in myobject.
All functions declared globally will be attached to the global window object. That's how JavaScript works.
JavaScript only has function scope. So any function declared inside another function is private to the outer function.
The function functionHopefullyInMyObjectCtx can not be accessed from outside yet.
myObject.myObjectFunction = function () {
var $this = this;
function functionHopefullyInMyObjectCtx() {
// code...
}
}
Declaring a function inside a function does not attach it to the this automatically. However the function remains private and is only accessible within the scope it was declared in.
If you wanted to access the functionHopefullyInMyObjectCtx function from myObject.myObjectFunction then here is a way:
var myObject = {};
myObject.myObjectFunction = function () {
return {
functionHopefullyInMyObjectCtx: function() {
console.log('I got called');
}
}
}
obj = myObject.myObjectFunction();
//obj now has ref to the inner function
obj.functionHopefullyInMyObjectCtx();
I got called
Here is a good read: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions
I believe I have found the answer I was looking for.
Why are variables automatically assigned to the global/window object?
Because the JavaScript engine keeps a 'global environment record' of the items declared within the global scope (just like all scopes have an environment record holding all declaration information), but the difference between the global environment record and normal scope environment records is that the engine makes this record accessible within code (not just for engine internal use), through the window object!
If I am wrong or it's not quite right, please go ahead and correct me.
Thank you for your help.
https://es5.github.io/x10.html#x10.2.3
Difference between variable declaration syntaxes in Javascript (including global variables)?

call or access a local function by name

function f1 () {
console.log('f1')
}
var s = 'f1'
runLocalFunctionByName(s)
Is this possible at all to write runLocalFunctionByName() or just call f1 without typing f1 in the source code, but using a variable holding its name? I mean without modifying f1 into a method, that answer is obvious: just make myobj.f1 = function or declare it globally like f1= function(). I am talking about normal local functions declared with function keyword only, not as vars, global vars or some other object property.
Not without the use of eval, which is evil (when used for this purpose for sure!).
Global functions could be called as attributes of the window object, but if they are in a local/closure scope that's not possible.
If you need to call functions by name, the only proper solution is storing them as attributes on an object, and then using obj[s]() for calling them.
One way of doing this is by using the instantiating a Function object.
var runLocalFunctionByName = function(fName) {
return (new Function('','return '+fName+'();'))();
};
Calling runLocalFunctionByName with a name of a function will now return the output of the named function.
EDIT
In case of local functions, the scope has to be mentioned, so we can modify the code, such that:
var runLocalFunctionByName = function(fName, scope) {
return (new Function('','return '+(scope?scope:'this')+'.'+fName+'();'))();
};
You can't access a local function outside its scope until unless you assign it to a variable having an accessible scope. MDN: A function defined by a function expression inherits the current scope. That is, the function forms a closure. On the other hand, a function defined by a Function constructor does not inherit any scope other than the global scope (which all functions inherit)

nodejs variable only in function and sub-functions

I'm trying to run the same function multiple times at once but if I create a local one with var variablename the sub-functions dont recognize it. And if I make it global, all instances of the Function will overwrite it.
function vladimir(){
var test="hello";
hanspeter();
}
function hanspeter(){
console.log(test);
}
console.log outputs undefined.
You're running into a scoping issue here.
When you declare methods without using var (function <function_name>() {}), those function declarations are moved to the top of the local scope (called function hoisting, if you want to look it up).
If you manually declare you functions, you have to wait until they are both declared before you can use them. This is because the first function won't know about any functions declared under it.
You've also got an issue where variables aren't being scoped. If you have a variable that you declare in one function, it isn't guaranteed to be there in another (since it is a different scope).
If you want to pass these variables around, the easiest way is to pass these into the function parameters, which will be reachable in your other function.
So in your simple example, you could get it to work like this:
var hanspeter = function (test) {
console.log(test);
}
var vladimir = function() {
hanspeter( "hello" );
}
Use function arguments:
function vladimir(){
var test="hello";
hanspeter(test);
}
function hanspeter(arg){
console.log(arg);
}
https://learn.jquery.com/javascript-101/functions/
JavaScript uses lexical scoping - it looks like you're expecting dynamic scoping. Essentially what this means is that a function has access to variables based on where it is declared, not where it is called. For example, the following would work:
function vladimir(){
var test="hello";
function hanspeter(){
console.log(test);
}
hanspeter();
}
Because test exists where hanspeter is declared. But in yours, test exists where hanspeter is called, which does not give it access.
You can also get variables by passing them:
function vladimir(){
var test="hello";
hanspeter(test);
}
function hanspeter(test2){
console.log(test2);
}
I called the argument to hanspeter test2 to show that it is the argument's name that matters, not the name of the variable being passed.

what is self-executing anonymous function or what is this code doing?

var module = {};
(function(exports){
exports.notGlobalFunction = function() {
console.log('I am not global');
};
}(module));
function notGlobalFunction() {
console.log('I am global');
}
notGlobalFunction(); //outputs "I am global"
module.notGlobalFunction(); //outputs "I am not global"
Can anyone help me understand what's going on here? I get that if you call notGlobalFunction(), it will just call the second function.
But what is var module = {} doing? and why is it called again inside the first function?
It says this is commonly known as a self-executing anonymous function but I don't really know what that means.
Immediately invoked functions are typically used to create a local function scope that is private and cannot be accessed from the outside world and can define it's own local symbols without affecting the outside world. It's often a good practice, but in this particular case, I don't see that it creates any benefit other than a few more lines of code because it isn't used for anything.
This piece of code:
(function(exports){
exports.notGlobalFunction = function() {
console.log('I am not global');
};
}(module));
Would be identical to a piece of code without the immediate invocation like this:
module.notGlobalFunction = function() {
console.log('I am not global');
};
The one thing that is different is that in the first, an alias for modules called exports is created which is local to the immediately invoked function block. But, then nothing unique is done with the alias and the code could just as well have used modules directly.
The variable modules is created to be a single global parent object that can then hold many other global variables as properties. This is often called a "namespace". This is generally a good design pattern because it minimizes the number of top-level global variables that might conflict with other pieces of code used in the same project/page.
So rather than make multiple top level variables like this:
var x, y, z;
One could make a single top level variable like this:
var modules = {};
And, then attach all the other globals to it as properties:
modules.x = 5;
modules.y = 10;
modules.z = 0;
This way, while there are still multiple global variables, there is only one top-level global that might conflict with other pieces of code.
Similarly, an immediately invoked function creates a local, private scope where variables can be created that are local to that scope and cannot interfere with other pieces of code:
(function() {
var x, y, z;
// variables x, y and z are available to any code inside this immediately invoked function
// and they act like global variables inside this function block and
// there values will persist for the lifetime of the program
// But, they are not truly global and will not interfere with any other global
// variables and cannot be accessed by code outside this block.
// They create both privacy and isolation, yet work just as well
})();
Passing an argument into the immediately invoked function is just a way to pass a value into the immediately invoked function's scope that will have it's own local symbol:
(function(exports) {
// creates a local symbol in this function block called exports
// that is assigned an initial value of module
})(module);
This creates a new empty object:
var module = {};
It does the same as:
var module = new Object();
This wrapper:
(function(exports){
...
}(module));
only accomplishes to add an alias for the variable module inside the function. As there is no local variables or functions inside that anonymous function, you could do the same without it:
module.notGlobalFunction = function() {
console.log('I am not global');
};
An anonymous function like that could for example be used to create a private variable:
(function(exports){
var s = 'I am not global';
exports.notGlobalFunction = function() {
console.log(s);
};
}(module));
Now the method notGlobalFunction added to the module object can access the variable s, but no other code can reach it.
The IIFE is adding a method to the module object that is being passed in as a parameter. The code is demonstrating that functions create scope. Methods with the same name are being added to a object and the the head object (window) of the browser.
"self-executing" might be misleading. It is an anonymous function expression, that is not assigned or or given as an argument to something, but that called. Read here on Immediately-Invoked Function Expression (IIFE).
what is var module = {} doing?
It initializes an empty object that is acting as a namespace.
why is it called again inside the fist function?
It is not "called", and not "inside" the first function. The object is given as an argument ("exports") to the IEFE, and inside there is a property assigned to it.

what's the difference between var function and function in javascript? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
JavaScript: var functionName = function() {} vs function functionName() {}
Function declaration - Function Expression - Scope
I've learned about var a = 1, is defining a local variable, but talk about function, I thought It's only available within the current scope as the var variable behave, what's the difference between the following two code snippet?
function aPrint() {
console.log('a');
}
var a = function aPrent() {
console.log('a');
}
Your first example is a "function declaration". It declares a function that will be available anywhere in the scope in which it is declared (so you can call it before it appears in the source code). This is sometimes known as "hoisting" (as in, it gets hoisted to the top of its scope).
Your second example is a "named function expression". The variable declaration is hoisted to the top of the scope in which it is defined (like a function declaration) but the assignment still happens where you expect it to, so you can't call the function until after it has been assigned to the variable.
There is a third option, which is just a "function expression", where the function does not have a name (it's an anonymous function):
var a = function() {
console.log('a');
}
You will probably find that you have little use for named function expressions (although it can be useful when debugging), so it's usually better to use the anonymous function. In a named function expression, the name is only in scope inside the function itself, so you can't refer to the function by name normally.
here is a best article that may help you.
refer http://www.dustindiaz.com/javascript-function-declaration-ambiguity/
function aPrint() {}
Declares a function (but does not execute it).
It will usually have some code between the curly brackets.
var a = aPrint()
Declares a variable, invokes a function (aPrint) and sets the value of aPrint to the return of the function.
var a= new aPrint()
Creates a new instance of an object based on the aPrint function. So the variable is now an Object, not just a string or a number.
Objects can contain indexed strings, numbers and even functions, and you can add more stuff to them, they're pretty awesome. The whole concept of Object Oriented Programming (OOP) is based on this.

Categories