SitePoint Sponsor

User Tag List

Results 1 to 19 of 19
  1. #1
    SitePoint Guru phantom007's Avatar
    Join Date
    May 2008
    Posts
    752
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)

    Question Calling a function only once

    Hi

    I am trying to write a function that will generate a random number b/w 1-10 but what I also want is that the function should return the random number only once (no matter how many times we call it) unless we force it to generate it using a flag or something..I am stuck here, so please can someone help me?

    herez the code
    Code:
    var a = function(){
      	return Math.floor(Math.random() * (10 - 1) + 1); 
      
    };
    
    var b = a();
    
    console.log(b);
    JSBIN:
    http://jsbin.com/uMUhoJU/2/edit


    Thanks

  2. #2
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    6,056
    Mentioned
    219 Post(s)
    Tagged
    12 Thread(s)
    Hi there,

    Do you mean that the first time it is called it should generate the random number and return it.
    Then every time it is called after that, it should return the same number?

  3. #3
    SitePoint Guru phantom007's Avatar
    Join Date
    May 2008
    Posts
    752
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Yes, and apart from that if i pass a flag to the function, it should generate a new random number.

    Thanks

  4. #4
    SitePoint Wizard bronze trophy Jeff Mott's Avatar
    Join Date
    Jul 2009
    Posts
    1,314
    Mentioned
    19 Post(s)
    Tagged
    1 Thread(s)
    You can use a closure to simulate the behavior of a static variable.

    Code JavaScript:
    var a = (function () {
        var randomValue;
     
        return function (flagForceNewValue) {
            if (randomValue === undefined || flagForceNewValue) {
                randomValue = Math.floor(Math.random() * (10 - 1) + 1); 
            }
     
            return randomValue;
        };
    }());

    That being said, I think it would be better software architecture if this function didn't try to remember its state. It should just return a ranged random value, every time. Then whatever part of your application that uses that number should decide whether it wants to reuse the result it already has or whether it should get a new number.

    Also, you may have noticed that 10 is never one of the random numbers returned. The function is actually returning numbers in the range 1-9. Change (10 - 1) to just 10, and you should be all set.
    "First make it work. Then make it better."

  5. #5
    SitePoint Guru phantom007's Avatar
    Join Date
    May 2008
    Posts
    752
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    The term "closure" u mentioned is new to me, i tried reading it on wikipedia but what they explained didnt make any sense to me, may be because its too complicated. Could you please explain the meaning of closure in layman's terms?


    Thanks

  6. #6
    SitePoint Wizard bronze trophy Jeff Mott's Avatar
    Join Date
    Jul 2009
    Posts
    1,314
    Mentioned
    19 Post(s)
    Tagged
    1 Thread(s)
    Notice in the code I posted that there are two nested functions. The outer function is invoked and returns the inner function. Normally in languages such as Java or C/C++, when a function is done executing, its local variables are destroyed. But that's not always the case in JavaScript. The inner function can continue to reference the outer function's variables even after the outer function has finished executing. The outer function's variables are said to be in a closure.

    More info:

    https://developer.mozilla.org/en-US/...tions#Closures
    https://developer.mozilla.org/en-US/...s_and_closures
    https://developer.mozilla.org/en-US/...Guide/Closures
    "First make it work. Then make it better."

  7. #7
    SitePoint Guru phantom007's Avatar
    Join Date
    May 2008
    Posts
    752
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Jeff Mott View Post
    Notice in the code I posted that there are two nested functions. The outer function is invoked and returns the inner function. Normally in languages such as Java or C/C++, when a function is done executing, its local variables are destroyed. But that's not always the case in JavaScript. The inner function can continue to reference the outer function's variables even after the outer function has finished executing. The outer function's variables are said to be in a closure.

    I'd call that a brilliant explanation...



    Thanks

  8. #8
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    6,056
    Mentioned
    219 Post(s)
    Tagged
    12 Thread(s)
    Hi,

    There's not really much to add to what Jeff already said.
    Saying that, I just read this, which seems to answer the question you posed above.

  9. #9
    SitePoint Guru phantom007's Avatar
    Join Date
    May 2008
    Posts
    752
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by cancer10 View Post
    I'd call that a brilliant explanation...



    Thanks
    And since I like the way you explain things, may I request you to explain me another concept in JS, which is Prototypes in JS (http://en.wikipedia.org/wiki/Prototy..._programming)? I could not out much from that wiki article.


    Many thanks in advance

  10. #10
    SitePoint Member
    Join Date
    Sep 2013
    Posts
    13
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    Prototypal inheritance is a big subject. He can explain the basics to you but there's a lot to be learned.

  11. #11
    SitePoint Guru phantom007's Avatar
    Join Date
    May 2008
    Posts
    752
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by thetenfold View Post
    Prototypal inheritance is a big subject. He can explain the basics to you but there's a lot to be learned.


    I'd appreciate even if he can explain me the basics


    Thanks

  12. #12
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    6,056
    Mentioned
    219 Post(s)
    Tagged
    12 Thread(s)
    Quote Originally Posted by cancer10 View Post
    may I request you to explain me another concept in JS, which is Prototypes in JS
    There was a good discussion of this subject here, recently.

  13. #13
    SitePoint Wizard bronze trophy Jeff Mott's Avatar
    Join Date
    Jul 2009
    Posts
    1,314
    Mentioned
    19 Post(s)
    Tagged
    1 Thread(s)
    The others are right that it'll take more than the few sentences I spent on closures, but I'll give it a go and do my best to make the complexity seem simple.

    I'll be back with that in a day or two. Depends on how busy I'll be at work today.
    "First make it work. Then make it better."

  14. #14
    Hosting Team Leader silver trophybronze trophy
    cpradio's Avatar
    Join Date
    Jun 2002
    Location
    Ohio
    Posts
    5,235
    Mentioned
    154 Post(s)
    Tagged
    0 Thread(s)
    @cancer10 ; I was at a conference in Columbus in May, and one of the topics was "Understand Prototypal Inheritance", you can download the slides at https://github.com/stirtrek/2013MayS...nheritance.zip

    They may help you out.

    Edit:

    I haven't downloaded these so I'm not sure how much detail they include.

  15. #15
    SitePoint Wizard bronze trophy Jeff Mott's Avatar
    Join Date
    Jul 2009
    Posts
    1,314
    Mentioned
    19 Post(s)
    Tagged
    1 Thread(s)
    Quote Originally Posted by cancer10 View Post
    And since I like the way you explain things, may I request you to explain me another concept in JS, which is Prototypes in JS (http://en.wikipedia.org/wiki/Prototy..._programming)? I could not out much from that wiki article.


    Many thanks in advance
    The first thing to be aware of is that there are two things in JavaScript called "prototype." The first is a run-of-the-mill property that every function has.

    Code JavaScript:
    function f() {}
     
    console.log(f.prototype);

    (More on that later.) The second is an under-the-hood reference between objects. In the spec, this under-the-hood reference is typically written as [[Prototype]], and I'll continue that convention to distinguish between the two meanings of "prototype."

    The internal [[Prototype]] property is how JavaScript implements inheritance. Let's say there's an object A, and A's [[Prototype]] property points to an object B. When we access A.someProperty, then JavaScript first checks if that property exists in A. If it does, then it returns its value. Otherwise, JavaScript follows the [[Prototype]] property to B. JavaScript then checks if that property exists in B. If it does, then it returns its value. Otherwise, JavaScript once again follows the [[Prototype]] to the next object. It will continue doing this until either it finds the property or until it reaches an object whose [[Prototype]] is null. (The [[Prototype]] linkage from one object to another to another is called a "prototype chain.")

    There have been some non-standard ways to manipulate the [[Prototype]] property, such as Mozilla's __proto__ property, but today the standard is to use Object.create.

    Code JavaScript:
    // A plain object's [[Prototype]] is implicitly set to Object.prototype
    var base = {};
    /* Psuedo code: base.[[Prototype]] === Object.prototype */
    base.plugin = 'Lorem ipsum';
     
    // Object.create will give us a new object that has its [[Prototype]] set to the object we passed in
    var widget = Object.create(base);
    /* Pseudo code: widget.[[Prototype]] === base */
    widget.render = 'Exire est';
     
    var myWidget = Object.create(widget);
    /* Pseudo code: myWidget.[[Prototype]] === widget */
    myWidget.app = 'Cupis hominem';
     
    // When we access myWidget.app,
    // JavaScript checks the object "myWidget" for the property "app",
    // finds it, and returns its value
    console.log(myWidget.app);
     
    // When we access myWidget.render,
    // JavaScript checks the object "myWidget" for the property "render",
    // but doesn't find it, so follows myWidget's [[Prorotype]] to the object "widget",
    // JavaScript then checks the object "widget" for the property "render",
    // finds it, and returns its value
    console.log(myWidget.render);
     
    // When we access myWidget.plugin,
    // JavaScript checks the object "myWidget" for the property "plugin",
    // but doesn't find it, so follows myWidget's [[Prorotype]] to the object "widget",
    // JavaScript then checks the object "widget" for the property "plugin",
    // but doesn't find it, so follows widget's [[Prorotype]] to the object "base",
    // JavaScript then checks the object "base" for the property "plugin",
    // finds it, and returns its value
    console.log(myWidget.plugin);

    The mileage we get out of this [[Prototype]] behavior is all we really need to make useful and complex inheritance hierarchies. However, the powers that be wanted to make JavaScript more palettable to Java programmers. This is where constructor functions, their prototype property, and the "new" keyword come into play. These three things are used to make JavaScript look more like Java, even though it ultimately uses [[Prototype]] to make things work.

    We start with a constructor function. Technically, any function could be a constructor. It only depends on whether we choose to treat a function as such by invoking it with "new".

    Code JavaScript:
    function Widget() {
        this.constructed = true;
    }
     
    var instance = new Widget();

    When we invoke a function with "new", the first thing that happens is a new object is created (what we think of as the instance object). That instance object has its [[Prototype]] set... but set to what? This is where the function's prototype property becomes important. The instance object's [[Prototype]] property will be set to the constructor function's prototype property. Finally, the constructor function is executed, using the instance object as the value for "this".

    If we were to simiulate the behavior of "new", here's how that would look.

    Code JavaScript:
    function simulateNew(constructorFunction) {
        // Create a new object who's [[Prototype]] is the constructor function's prototype
        var instance = Object.create(constructorFunction.prototype);
     
        // Execute the constructor function using our new instance as "this"
        constructorFunction.call(instance);
     
        // Finally, return the new instance
        return instance;
    }
     
    // Now these two lines will do the same thing
    var instance = new Widget();
    var instance = simulateNew(Widget);

    Since every instance's [[Prototype]] will point to Widget.prototype, that means whatever functions or properties we assign to Widget.prototype will be available to every instance via the prototype chain.
    "First make it work. Then make it better."

  16. #16
    SitePoint Guru phantom007's Avatar
    Join Date
    May 2008
    Posts
    752
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    @Jeff Mott Ultimate explanation,

    Two questions for you now:

    1) How did you grab this in-depth knowledge of prototypes? Books? videos?? Pls share.

    2) Consider the following example:

    Instead of doing this:
    Code:
    myobj = function(fname){
     this.fname = fname;
    };
    
    myobj.prototype.age = function (age) {
       this.age = age;
    };
    
    var x = new myobj('joe');
    alert(x.fname);
    x.age = 32;
    alert (x.age);
    I can do this:
    Code:
    myobj = function(fname, age){
     this.fname = fname;
      this.age = age;
    };
    
    
    
    var x = new myobj('joe', 32);
    alert(x.fname);
    alert (x.age);
    So what do we need prototype for?

    Any explanations will be appreciated.

    Thanks

  17. #17
    SitePoint Wizard bronze trophy Jeff Mott's Avatar
    Join Date
    Jul 2009
    Posts
    1,314
    Mentioned
    19 Post(s)
    Tagged
    1 Thread(s)
    Quote Originally Posted by cancer10 View Post
    1) How did you grab this in-depth knowledge of prototypes? Books? videos?? Pls share.
    The two best sources that stick out in my mind are Crockford's Advanced JavaScript presentation and the ECMAScript spec.

    Quote Originally Posted by cancer10 View Post
    2) Consider the following example:

    Instead of doing this:
    Code:
    myobj = function(fname){
     this.fname = fname;
    };
    
    myobj.prototype.age = function (age) {
       this.age = age;
    };
    
    var x = new myobj('joe');
    alert(x.fname);
    x.age = 32;
    alert (x.age);
    I can do this:
    Code:
    myobj = function(fname, age){
     this.fname = fname;
      this.age = age;
    };
    
    
    
    var x = new myobj('joe', 32);
    alert(x.fname);
    alert (x.age);
    So what do we need prototype for?

    Any explanations will be appreciated.

    Thanks
    So, the difference I see is whether to set a value through the constructor or through a setter method. Is that what you're trying to ask? If so, then this is a fairly general design question (not specific to JavaScript or prototypes), and there isn't an inherent right or wrong answer. If the age is considered to be a required value, then accepting it in the constructor will probably make the most sense most of the time. Or if the age is considered to be an optional value, then using a setter may make the most sense.
    "First make it work. Then make it better."

  18. #18
    Non-Member
    Join Date
    Feb 2012
    Posts
    892
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by cancer10 View Post
    2) Consider the following example:

    Instead of doing this:

    I can do this:

    So what do we need prototype for?

    Any explanations will be appreciated.

    Thanks
    Actually, you are way into error here. You seem to not distinguish between properties and method properties, i.e. myobj.prototype.age() and obj.age.

    The problem with the first example, is that you add a method to prototype, and later, when you do this x.age = 32, age is now a simple property, it's not a method anymore.

    Here is how the x object looks like before x.age = 32: Object { fname="joe", age=function()}, and how it looks after: Object { fname="joe", age=32}.

    The prototype chain is game only if the object doesn't have a property with the same name that is found first.

    You've "transformed" age from a method property into a simple property.

    Your first example should look like this:
    Code:
    myobj = function(fname, birthday){
     this.fname = fname;
     this.birthday = birthday;
    };
    
    myobj.prototype.age = function() {
      return years(this.birthday);
    };
    
    myApi.prototype.years = function(startDate) {
      var today = new Date();
    // TODO
    };
    As you can see age is a method that returns the age, is not a fixed property.

    As per you point, why use prototype.

    If we put the age method in the constructor, then every x built from myobj will have its own set of methods, i.e. how many x's that many age methods.

    Whereas if we put it in prototype, there will be but one age method shared by all of your x's.

    The most clear analogy I can think of when it comes to properties in the constructor or properties in the prototype is the same difference between passing by value or passing by reference.
    Last edited by myty; Oct 6, 2013 at 03:48. Reason: Corrected a few mistakes, cutted some wrong parts.

  19. #19
    Non-Member
    Join Date
    Feb 2012
    Posts
    892
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Jeff Mott View Post
    So, the difference I see is whether to set a value through the constructor or through a setter method. Is that what you're trying to ask? If so, then this is a fairly general design question (not specific to JavaScript or prototypes), and there isn't an inherent right or wrong answer. If the age is considered to be a required value, then accepting it in the constructor will probably make the most sense most of the time. Or if the age is considered to be an optional value, then using a setter may make the most sense.
    Since JavaScript is the only mainstream language that uses prototype inheritance, this is not a general design question.

    Putting a method in the constructor in JavaScript means that every object based on this object will have its own set of those methods. On the one hand this mean more occupied memory, on the other hand, when later you want to alter one property these objects have in common, you have to go through all these objects and modify it, unless you've put it in the prototype. If it's in the prototype, and when you modify it there, all the objects will get the modification at once.


Bookmarks

Posting Permissions

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