www.webdeveloper.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 22

Thread: Another dumb question about scope

  1. #1
    Join Date
    Mar 2011
    Posts
    19

    Another dumb question about scope

    Hi there,

    Sorry for the dumb question, I've been googling all over and I can't find an answer to ths.

    I notice that if I do this:
    Code:
    var fnc = function() {
      var a = 10;
      fnc.b = 10;
    }
    fnc.c = 4
    alert(fnc.a);
    alert(fnc.b);
    alert(fnc.c);
    the first two alerts show undefined and the third shows 4. Presumably c is defined as an attribute of fnc. My question is, why are a and b not attributes of fnc.

    Sorry again for the dumb question

  2. #2
    Join Date
    Mar 2011
    Posts
    19
    Also, is there a way to declare a such that it is accessible from fnc.a?

  3. #3
    Join Date
    Apr 2011
    Posts
    7
    hi,

    You have effectively declared a variable "a" and an associative array "fnc.b", which are both local to a function. You never return anything from that function and you are not trying to populate already declared (and therefore global variables) - hence when you try to call on these they are null. You then globally set an associative array "fnc.c", which is why this is the only one that gives output when you run your alerts.

    If you had declared the associations fnc.a, fnc.b and fnc.c before your function call, then you could indeed set them within the function.

    hope that makes sense,

    skinicod.

  4. #4
    Join Date
    Mar 2011
    Posts
    19
    Thanks skinicod,

    As far as I can see though, fnc is and remains a variable of type function. If I do:

    Code:
    var fnc = function() {
    }
    fnc.c = 4
    alert(fnc)
    alert(fnc.c);
    the function literal is displayed. When I set fnc.c I think I'm setting it on the function itself. My question is then, is there a way from within the function literal to access fnc.c? Surely functions can access their own members?

  5. #5
    Join Date
    Apr 2011
    Posts
    7
    Hi goldfidget,

    I'm not really sure why you're trying to do what your doing, but I think the reason you are not being able to set fnc.c was returning null, is that you have only ever defined the function literal and not actually called it.

    If you call it, it will set correctly, and be useable outside the function e.g.

    Code:
    var fnc = function fnc() {
    	fnc.c = 5;
    }
    
    fnc();
    
    alert(fnc)
    alert(fnc.c);
    Does this help?

    Cheers,

    Skinicod

  6. #6
    Join Date
    Dec 2003
    Location
    Bucharest, ROMANIA
    Posts
    15,428
    You confound functions with objects. A function can be used to create an object (or can be handled as an object), but an object is not a function. An object have members. A function has no literal members, or better say, the declarations, expressions, variables, etc defined inside a function are not members of that function , even if treated as an object.

    If you want to access literally the members of an object, either you should write literally that object
    Code:
    var fnc = {
    a:10,
    b:10
    }
    fnc.c = 4;
    Or you may use another function as a constructor
    Code:
    var Constructor = function(a,b,c){
    	this.a=a;
    	this.b=b;
    	this.c=c;
    }
    fnc = new Constructor(10,10,4);
    A function is, in fact an object generated by the Function() native constructor.

    And something else. In you code you have used a function expression:
    Code:
    var fnc = function(){
    }
    That does nothing but to assign an anonymous function to a variable.

    A function can be invoked from inside, if this is what you are looking for, using the combination of the function's properties arguments and callee
    Code:
    var fnc = function(){
    	alert(arguments.callee.c);
    }
    fnc.c=4;
    fnc();
    More about functions (and Function) scope:
    https://developer.mozilla.org/en/Jav...function_scope
    Last edited by Kor; 04-04-2011 at 08:42 AM.

  7. #7
    Join Date
    Mar 2011
    Posts
    19
    Thanks Kor,

    My assumption, coming from Ruby, was that functions are a type of object.

    Code:
    var str = "Hello";
    str.a = "Hi There";
    alert(str.a);
    // => undefined
    Code:
    var fnc = function() {}
    fnc.a = "Hi There";
    alert(fnc.a);
    // => "Hi There"
    Do I take it then that in Javascript, only objects are object. Strings are not objects, functions are not objects, etc?

    If so, then why the different behaviour for the two examples above?

    Thanks

  8. #8
    Join Date
    Apr 2011
    Posts
    7
    Hi goldfidget,

    This is my third attempt to reply to you, but unfortunately my replies are going into ether..

    Anyway - you can give a function literal members (though I'm not entirely sure why you would). The only reason you haven't been having success, is that you haven't actually called the function - you've only set it. if you call add 'fnc();' after you declare the literal, any member declarations within it will be processed.

    Cheers,

    skinicod.

  9. #9
    Join Date
    Dec 2003
    Location
    Bucharest, ROMANIA
    Posts
    15,428
    Everything is or can be treated as an object in JavaScript. But not everything is an Object. What I wanted to emphasize is that the expressions written literal inside a function are not members of the function.

    In JavaScript the strings are primitives, and derive from the native String object/method. But you can set them as Objects, by using straight the source of their derivation (the String() method):
    Code:
    var str = new String("Hello")
    str.a="Hi There"
    alert(str.a)
    It is the same as we saw in declaring the functions.
    Code:
    var str="Hello"; // this is an expression, the result is a primitive String
    var str = new String("Hello"); // this is a construction, the result is an object String
    Coming back to the primitives: if you want to add custom members to a primitive, you can do it by alter its prototype.
    Code:
    String.prototype.a="Hi There";
    var str = "Hello";
    alert(str.a);
    But that method (extended prototype) will add a member to all the strings declared on the document.
    Last edited by Kor; 04-04-2011 at 09:20 AM.

  10. #10
    Join Date
    Dec 2003
    Location
    Bucharest, ROMANIA
    Posts
    15,428

  11. #11
    Join Date
    Dec 2003
    Location
    Bucharest, ROMANIA
    Posts
    15,428
    Quote Originally Posted by skinicod View Post
    Anyway - you can give a function literal members (though I'm not entirely sure why you would). The only reason you haven't been having success, is that you haven't actually called the function - you've only set it. if you call add 'fnc();' after you declare the literal, any member declarations within it will be processed.
    Yes and no. It will work in this case:
    Code:
    var fnc=function(){
    fnc.a=10
    }
    fnc();
    alert(fnc.a)
    But that would be the long equivalent of:
    Code:
    var fnc=function(){
    }
    fnc.a=10
    alert(fnc.a)
    Which does not change the essence of the function expression.

  12. #12
    Join Date
    Mar 2011
    Posts
    19
    Ah, that's interesting, the String constructor wraps a string primitive in an object.

    The primitive still has methods though, I can do this:

    Code:
    alert("Hello".charAt(2));
    => l

  13. #13
    Join Date
    Mar 2011
    Posts
    19
    Ah I see, that makes sense. The code is not evaluated until the function is run, so until I call fnc(), fnc.c does not exist...

    Quote Originally Posted by skinicod View Post
    Hi goldfidget,

    I'm not really sure why you're trying to do what your doing, but I think the reason you are not being able to set fnc.c was returning null, is that you have only ever defined the function literal and not actually called it.

    If you call it, it will set correctly, and be useable outside the function e.g.

    Code:
    var fnc = function fnc() {
    	fnc.c = 5;
    }
    
    fnc();
    
    alert(fnc)
    alert(fnc.c);
    Does this help?

    Cheers,

    Skinicod

  14. #14
    Join Date
    Dec 2003
    Location
    Bucharest, ROMANIA
    Posts
    15,428
    The primitive still has methods though
    Yes. Some JavaScript primitives have their native properties and their methods. But JavaScript makes a difference between native properties/methods and custom properties/methods in case of Primitives (and not only primitives, and not all the Primitives).

    One says that "JavaScript primitive values, Booleans, numbers, and strings, are pseudo-objects". They have native properties and methods, but they can not individually gain custom properties/methods. They may gain only "collective" native properties/methods, by altering the prototype of their source of derivation (their "wrapper") - ex String for strings, Number for numbers, Boolean for booleans.

    The other two primitive groups in javascript (after string, number and boolean) are null and undefined. Interesting enough, null is an object, but it has no properties/methods (it is a sort of anti-object = an object which "measures" the existence, or better say, the non-existence of an object), while undefined it is not an object at all, it is a pure primitive value.

  15. #15
    Join Date
    Mar 2011
    Posts
    19
    Quote Originally Posted by Kor View Post
    More about functions (and Function) scope:
    https://developer.mozilla.org/en/Jav...function_scope
    Ah, sorry, I missed your link. Functions are objects, string literals are not.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center



Recent Articles