8

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.

HILARUDEEN S ALLAUDEEN
  • 1,722
  • 1
  • 18
  • 33
  • Possible duplicate of [Static variables in JavaScript](http://stackoverflow.com/questions/1535631/static-variables-in-javascript/1535687#1535687) – Givi Jul 31 '13 at 10:22
  • in js function is also object so you can add a property to it, – Arun Killu Jul 31 '13 at 11:43
  • 1
    Take a look [***jsFiddle***](http://jsfiddle.net/GKDev/TdF94/) *maybe this is what you wanted to know.* – Givi Jul 31 '13 at 12:14

4 Answers4

5

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.
Thilo
  • 257,207
  • 101
  • 511
  • 656
  • +1, simple as that. I am a little confused what the other answers are about. – Dennis Jul 31 '13 at 10:24
  • Yes, I accept it. is there any code violation in that? Is this affect any performance? – HILARUDEEN S ALLAUDEEN Jul 31 '13 at 10:26
  • Affect performance compared to what? There is no difference to referring to any other object in the enclosing scope, does not matter that you are referring to the function itself or something completely unrelated. – Thilo Jul 31 '13 at 10:28
  • I haven't seen coding style any where like mentioned in my question. I know that writing Myfunction.myvar = "somevar"; outside of "Myfunction" is good practice . If I compare these two, is there any different in javascript engine's performance? – HILARUDEEN S ALLAUDEEN Jul 31 '13 at 10:43
  • @hilarudeens you mean, referring to a function from within itself? Not more than any access to any other variable within its surrounding scope. – John Dvorak Jul 31 '13 at 10:47
  • @Jan Dvorak No, I completely agree with Thilo. Just I want to know why don't we do like this on creating static variable? or nothing wrong. – HILARUDEEN S ALLAUDEEN Jul 31 '13 at 10:59
4

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
};
James Allardice
  • 164,175
  • 21
  • 332
  • 312
2

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"
};
Sebastian Baltes
  • 512
  • 5
  • 14
  • If you call function constructor without new operator it'll create global variable named `Myvar`, because this will refer to window object, but in strict mode it will cause an error, because this will be undefined. [look at](http://jsbin.com/opoker/1/edit) – Givi Jul 31 '13 at 11:00
  • I wasn't maybe clear enough, my second code block var x = Myfunction(); was related to the original code from the question. A global variable (meaning in the surrounding context) named Myvar will only be created if the function uses this instead of the function name. – Sebastian Baltes Jul 31 '13 at 11:19
  • If OP call `var x = Myfunction();` value of `x` will be `undefined` and x.Myvar will cause an error... he simply creates a static variable inside function when it will be called. So, if you want to get value of `Myvar` you should use `Myfunction.Myvar`. – Givi Jul 31 '13 at 11:33
  • 1
    I stripped down my answer from the misleading part – Sebastian Baltes Jul 31 '13 at 11:41
0

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);
mikach
  • 2,427
  • 2
  • 14
  • 15