Can I use function as an object inside the same function - javascript

I write the code as follows,
function Myfunction(){
Myfunction.myvar = "somevar";
}
After I execute the function, I can able to access Myfunction.myvar
How is it working? And If I do so, What is the problem hidden in this?
If any problem, please explain context of that.

Since the function does not execute until you call it, Myfunction.myvar is not evaluated immediately.
Once you call it, the function definition has been installed as Myfunction, so that it can be resolved when you do call it.
Something like the following would not work:
var x = {
foo: 1,
bar: x.foo } // x does not exist yet.

How is it working?
When you declare a function in some execution context, a binding is added to the variable environment of that context. When you reference an identifier, the current variable environment is checked to see if a binding exists for that identifier.
If no binding exists, the outer variable environment is checked, and so on, back up to the global scope.
So:
// OUTER SCOPE
// Binding exists for 'example'
function example() {
// INNER SCOPE
// No binding for 'example'
// References 'example' in outer scope
example.x = 1;
}
What is the problem hidden in this?
There are none (in general... although whether it's the right solution for you depends on what you're trying to do).
You are effectively creating a "static" property of the function. As JavaScript functions are first-class you can set properties on them as you would with any other object.
Note that the behaviour is different if you have a named function expression, rather than a function declaration:
var x = function example () {
// Identifier 'example' is only in scope in here
};

One problem you might get because of scoping, as a more complicate example shows:
function Other() {
console.log("a) Other.Myvalue",Other.Myvalue);
Other.Myvalue=typeof Other.Myvalue==='undefined' ? 0 : Other.Myvalue+1;
console.log("b) Other.Myvalue",Other.Myvalue);
}
Other();
Other();
this would lead to
a) Other.Myvalue undefined
b) Other.Myvalue 0
a) Other.Myvalue 0
b) Other.Myvalue 1
so you realy bind your variable Myvar to the function object itself which is a singleton and exists just once (and is created by the function definition itself in the current context which may be the global context), not to an instance of that object. But if you just use static values and don't need any logic, it's like the literal form, and I wouldn't expect any problems, other that the literal form is more convenient:
var Other = {
Myvalue: "somevalue"
};

In javascript every function is an object. So you can add any custom fields to it.
function A() {}
A.somevar = 'this is custom field';
A.prototype.somevar2 = 'this is field in A proto';
So when you will create new object with A contructor it will take properties from prototype.
var b = new A();
alert(b.somevar2);

Related

How variable "str2" is available inside the callback method

How the variable 'str2' is available inside the callback method passed to display method?
str2 should be visible only inside function 'name'.
a = {
display: function (n){
console.log("I am inside display method");
n();
}
}
function name(a,str2)
{
a.display(function (){
console.log(str2);
})
}
name(a, 'ddd');
Variable scoping in Javascript is hierarchical. Lower scopes have access to all variables of all higher scopes. Here's an example:
function outer() {
var foo = 2;
function inner() {
console.log(foo); // 2
}
}
It doesn't matter if a variable is passed as a parameter or if it was defined as a local var.
Yes str should be visible only inside function 'name' yes it is working same you said, in JavaScript function declarations loads before any code is executed, and scope depend on execution context
in your code scope of str2 is inside name() function and you call a.display() within this scope (within scope of name()) that's why str2 available inside display() at the time of execution.
To evaluate name(a, 'ddd'), the compiler will create a new stack frame and place two slots on it, one a, which will be a reference to the global object of the same name, and str2, which will contain the string literal 'ddd'. Then the body will be evaluated.
In the body, to evaluate a.display(function(){...}), the value of a.display will be resolved to the function with parameter n. To evaluate n(function(){...}), a new stack frame will be created with n assigned to the closure that results from evaluating the anonymous callback (a closure being a combination of a pointer to the static scope of the function and the compiler generated code for the function itself). Then the body of the a.display function will be evaluated.
In the body, the console.log will be called with the given string. Then the callback n() will be evaluated. Since n doesn't take any parameters, it will just be evaluated in the topmost stack frame, so when the time comes to evaluate console.log(str2), str will not be found on the current stack frame, so the compiler will follow the scope chain all the way to the frame where we bound 'ddd' to str and a to the function.
That's a pretty long answer to your simple question. I'll try to shorten it later. Also, corrections are welcome, as I'm being very hand-wavy with the evaluation process.
In Javascript the variable declared on a certain scope is available in every inner scope. In this case it's a concept called "closure". This answer might give you good insight about scoping in Javascript: What is the scope of variables in JavaScript?
Hope this simple example can help you understand its usefulness:
function counter () {
var votes = 0;
this.upvote = function() { votes++; }
this.downvote = function() { votes--; }
this.getValue = function() { return votes; }
}
var counter1 = new counter();
counter1.upvote();
console.log(counter1.getValue()) // Prints 1
counter1.upvote();
counter1.upvote();
console.log(counter1.getValue()) // Prints 3

Is it possible to Detect Closure Programmatically?

I have a function which allows user to pass a function.
function withPredicate(func){
//...
}
Inside my function, I need to detect whether the func that user pass in has closure or not.
It is not enough to get the function name and search it in window scope. User might pass in an anonymous function without closure like:
var func = function(x){return x;};
withPredicate(func);
EDIT:
I think I need to implement a function which takes a function as a argument and return bool.
function hasClosure(func){
//...
}
so several test cases are:
hasClosure(function(x){return x;}); //return false
var something = 30;
var func1 = function(x){return x.age < something;}
hasClosure(func1); //return false
var Closure = function(){
var something = 18;
var itself = function(x){
return x.age < something;
};
return itself;
};
var func2 = new Closure();
hasClosure(func2); //return true
The last one return true because func2 is not top-level function. When I see some free variable inside the function body like something, it may resolve to the variable defined in its closure other than the one defined in window.
Actually, what I need to do now is to do some manipulations based on the func that has been passed to my function. I can use JSLint to get the undeclared variable. But I also need to resolve these variables. It is acceptable that I can only resolve variables in global scope. But I still need a way to make sure that resolving these variables in global scope is correct. So I need to detect closures.
Is it possible to do that programmatically in javascript?
Alright this is really hacky and probably not worth the effort in actually writing unless your linting or something :)
Basically what you're going to have to do to determine if a function is a closure is call func.toString() which will give you the source of the function. You can then parse the function using some sort of parser which determines all the variables of the function func. You also need to determine and track how these variables are defined. In your criteria in op the criteria for it being a closure is having a variable that is defined outside of function scope and outside of window scope (thus closure scope). So if you can find any variables defined outside of these two scopes we've found a closure.
So heres the pseudocode of hasClosure(), have fun implementing.
func hasClosure(func)
source = func.toString(); //eg "function x(a) {return new Array(a)}"
variables = parseJSForVariables(source)//finds a and Array
for variable in variables:
if(variable not in window)
if(variable not defined in function)
return true //we got a closure
return false //not a closure
The correct answer highly depends on what a "closure" means in this context. The function from the question does not use the variables from the outer scope so, roughly, closure is not created for this function. But strictly speaking, closure is created for any function and binds definition context with the function. So whatever you want to detect, it requires a detailed specification.
But I can assume that the closure here means whether the function references variables declared in outer scope (just like https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures specifies). One of the static for analysis libraries can be used for this. For example, JSLint reports used but undeclared variables. Assuming that undeclared variables are just from the upper scope, this indicates that closure is created.

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.

Still confused about JavaScript's 'this'

I've been reading through quite a few articles on the 'this' keyword when using JavaScript objects and I'm still somewhat confused. I'm quite happy writing object orientated Javascript and I get around the 'this' issue by referring the full object path but I don't like the fact I still find 'this' confusing.
I found a good answer here which helped me but I'm still not 100% sure. So, onto the example. The following script is linked from test.html with <script src="js/test.js"></script>
if (!nick) {
var nick = {};
}
nick.name= function(){
var helloA = 'Hello A';
console.log('1.',this, this.helloA);
var init = function(){
var helloB = 'Hello B';
console.log('2.',this, this.helloB);
}
return {
init: init
}
}();
nick.name.init();
What kind of expected to see was
1. Object {} nick.name, 'Hello A'
2. Object {} init, 'Hello B'
But what I get is this?
1. Window test.html, undefined
2. Object {} init, undefined
I think I understand some of what's happening there but I would mind if someone out there explains it to me.
Also, I'm not entirely sure why the first 'console.log' is being called at all? If I remove the call to the init function //nick.name.init() firebug still outputs 1. Window test.html, undefined. Why is that? Why does nick.name() get called by the window object when the html page loads?
Many thanks
Also, I'm not entirely sure why the first 'console.log' is being called at all?
nick.name = function(){
// ...
}();
Here you define a function, call it immediately (hence ()) and assign its return value ({init: init}) to nick.name
So the execution is:
Create a variable called nick if there isn't one with a non-falsey value already
Create an anonymous function that…
Creates a variable called helloA in its own scope
Outputs data using console.log containing "1" (as is), this (the window because the function is executing in the global context instead of as a method), and this.helloA (window.helloA, which doesn't exist.
Defines a function called init
Returns an object which gets assigned to nick.name
Then you call nick.name.init() which executes the init function in the context of name.
This defines helloB
Then it console.logs with "2" (as is), this (name), and this.helloB (nick.name.helloB - which doesn't exist)
So the first output you get is from console.log('1.',this, this.helloA);
I think your main problem is that you are confusing this.foo (properties on the object on which a method is being called) with variable scope (variables available to a function)
It's much simpler if you think about this as a function, not as a variable. Essentially, this is a function which returns current "execution context", that is, the object the current function was "applied" to. For example, consider the following
function t() { console.log(this)}
this will return very different results depending upon how you call it
t() // print window
bar = { func: t }
bar.func() // print bar
foo = { x: 123 }
t.apply(foo) // print foo
this is defined on a per-function basis when the function call is made. When you call a function as o.f(), this will be o within the function, and when you call it as f(), this will be the global object (for browsers, this is the window).
You wrote nick.name = function(){...}(); and the right-hand part is of the form f(), hence the Window.
var foo = bar; defines a local variable. It may not be accessed as this.foo (well, except when you're at global scope, but that's silly). To define a member, you usually write this.foo = bar; instead.
This is what your code does:
It creates an object and assigns to the variable nick.
It creates an anonymous function.
It calls the function (in the window scope).
It assigns the return value (an object containing the init property) to the name property of the object.
It gets the value from the init property, which is a method delegate, and calls the method.
The anonymous function does this:
It declares a local variable named helloA and assigns a string to it. (Creating a local variable doesn't add it as a property to the current object.)
It logs this (window) and the helloA property (which doesn't exist).
It creates an anonymous function and assignes to the local variable init.
It creates an object with the property init and the value from the local variable init.
The anonymous function assigned to the init property does this:
It declares a local variable named helloB and assigns a string to it. (Creating a local variable doesn't add it as a property to the current object.)
It logs this (the object from the name property, not the nick variable), and the helloB property (which doesn't exist).

how does memory stacks work in javascript

When we have code like:
function a(){
var x =0;
this.add=function(){
alert(x++);
}
}
var test = new a();
test.add(); // alert 0
test.add(); // alert 1
test.add(); // alert 2
How does this work?
Doesn't that the value of 'x' in a() should be 'gone' as soon as test = new a() is complete? The stack contains x should also be gone as well, right? Or, does javascript always keep all the stacks ever created in case they will be referenced in future? But that wouldn't be nice, would it...?
The word you're looking for is “closure”.
Creating a function inside another function gives the inner function a (hidden) reference to the local scope in which the outer function was running.
As long as you keep a copy of your test, that has an explicit reference to the add function, and that function has an implicit reference to the scope created when calling the a constructor-function. That scope has an explicit reference to x, and any other local variables defined in the function. (That includes the this value and the constructor's arguments — though you can't access them from inside add as that function's own this/arguments are shadowing them.)
When you let go of test, the JavaScript interpreter can let go of x, because there's no way to get a reference back to that variable.
What you're seeing is the effect of a closure. The function being defined within the other function gets access to all of the variables and such in scope where it is — even after the outer function returns. More here, but basically, the variables (and arguments) in the function all exist as properties on an object (called the "variable object") related to that function call. Because the function you've bound to this.add is defined within that context, it has an enduring reference to that object, preventing the object from being garbage-collected, which means that that function can continue to access those properties (e.g., the variables and arguments to the function).
You normally hear people saying that the function closes over the x variable, but it's more complex (and interesting) than that. It's the access to the variable object that endures. This has implications. For instance:
function foo() {
var bigarray;
var x;
bigarray = /* create a massive array consuming memory */;
document.getElementById('foo').addEventListener('click', function() {
++x;
alert(x);
});
}
At first glance, we see that the click handler only ever uses x. So it only has a reference to x, right?
Wrong, the reference is to the variable object, which contains x and bigarray. So bigarray's contents will stick around as well, even though the function doesn't use them. This isn't a problem (and it's frequently useful), but it emphasizes the underlying mechanism. (And if you really don't need bigarray's contents within the click handler, you might want to do bigarray = undefined; before returning from foo just so the contents are released.)

Categories