1

i have a question about JavaScript. I know how to use prototype, and why is it used, but i have tried to answer me this question, what will happen if i use prototype in a function like this,

var Command = function () {
    var text = 'Hello World';

    Command.prototype.run = function () {
        console.log(text);
    };
};

var command = new Command();
command.run();

Now I will be able to use also the private functions or variables. I have build with jsFiddle examples, with all variants and it shows that there seems no difference where I used prototype. But may I have overlocked something?

Tushar
  • 85,780
  • 21
  • 159
  • 179
HerrHase
  • 11
  • 1
  • i do not really understand your question - does your code work? – messerbill Nov 04 '15 at 11:36
  • Yes it works, my question is if it is a problem to use prototype in a function, alle references about this topics used prototype outside the main function. – HerrHase Nov 04 '15 at 11:41
  • @nirgendswo: No, it **does not work**. Try to use it with multiple instances and see it fail. – Bergi Nov 04 '15 at 13:31
  • I have, no Problems there, i have created it multiple times. But the real Problem is, that each time the prototype will redefined, what it is a little waste of space ;-) – HerrHase Nov 04 '15 at 15:03
  • @nirgendswo: Your example code might continue to work with multiple instances because `text` is static. But once you start to modify it, hell will break open… – Bergi Nov 04 '15 at 22:38
  • @Bergi i think not, http://jsfiddle.net/nirgendswo/kencyz55/ – HerrHase Nov 05 '15 at 10:27
  • 1
    @Bergi ah, now i understand what you mean, "text" will be have the same value in all instances, if i change him, all instances share it. Thanks for your comment :) – HerrHase Nov 05 '15 at 10:53

3 Answers3

1

If you set the run() function on a function's prototype inside the function, then it will be redefined every time the function is run.

That's pointless (as you could just define another function rather than setting the prototype), inefficient (as you're doing identical work over and over again) and another developer looking at your code won't understand why you did it when you could have defined it outside the function.

That'll be why you don't see other people doing it. Defining run() outside your function on the prototype defines it once. It's idiomatic JS, eg. MDN.

I'm not aware of any technical problem with doing it.

brabster
  • 42,504
  • 27
  • 146
  • 186
  • As an aside, I can see why it might feel more natural to define a function the way you have - ES6 classes https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes give you syntactic sugar over the prototype mechanism for a more classic OO feel. – brabster Nov 04 '15 at 13:19
  • That is the main reason more Structure, and use of private function and parameters. ES6 is great, but not usable for each project ;-) – HerrHase Nov 04 '15 at 15:05
  • ah.. ok - when you add a something to a prototype, it's not private wherever it's done. Defining things in closures is typically how you get privacy in JS. – brabster Nov 04 '15 at 15:12
-1

The var test is being closed over by the function expression Command.prototype.run. This is called closure.

var Command = function () {
    var text = 'Hello World';

    Command.prototype.run = function () {  // text is closed over by this function
        console.log(text);
    };
};
Command.prototype.run1 = function () { // text is not in scope and thus not available.
    console.log(text);
};

var command = new Command();
command.run();  // this will work and display what is in text
command.run1();  // this will fail and throw text undefined error.

Generally if a variable is in scope where you define the function it will be available to that function. If not then you don't have access to it.

Blindman67
  • 51,134
  • 11
  • 73
  • 136
  • I know, but my question, is there any problem wen i use prototype in a function. All references about this topic used prototype outside the main function. – HerrHase Nov 04 '15 at 11:40
-1

Prototype using has memory management advantages. If you don't use prototype, when you create new object, you will have to create new function with this.

var Command = function () {
    var text = 'Hello World';

    //One time create this function
    Command.prototype.run = function () {
        console.log(text);
    };

     this.test= function(){
       console.log(text);
     }
};

var command = new Command(); //again created test function, because it doesn't have a prototype
command.run();
command.test();
egvrcn
  • 974
  • 10
  • 27
  • I know, but my question, is there any problem wen i use prototype in a function. All references about this topic used prototype outside the main function. – HerrHase Nov 04 '15 at 11:42
  • 1
    @nirgendswo No there is no problem. But if the prototype is inside the function the prototype is redefined each time you create a new Command object. If you only create it once then it does not matter. If you are creating many of them then it will make a difference but marginal. If you are making millions of them the avoid it. – Blindman67 Nov 04 '15 at 11:45
  • @Blindman67 so from your comment above your test function equal to run fucntion in a few specific ways. The test function also creates when we are trying to create a new object. Is it correct? And also -run_ function you always override am i right ? – The Reason Nov 04 '15 at 13:14
  • @Blindman67: There is a *huge* problem but apparently no one sees it. – Bergi Nov 04 '15 at 13:34
  • @Bergi The use of prototype to define methods and assign properties is by far the most inefficient way to define objects. The use of closure is a valid and in my view an important part of javascript object structuring, to use it does incur additional overhead, but this is minor (considering the overhead any prototypes inccure). Hidden properties (private) are meant to protect objects from incorrect use and are an important part of good design. To state there is a "huge" problem without reasoning or explanation, benefits no one and detracts from the professionalism of this site. – Blindman67 Nov 04 '15 at 22:26
  • @Blindman67: I think you got that backwards, methods on the prototype are more efficient (better optimised) than privileged instance-specific methods in current JS engines. Regardless, the huge problem with the OPs code is that the prototype method (for all instance) closes over the private variable of the last create instance - as is also explained in [the question](http://stackoverflow.com/q/28255957/1048572) I closed this a duplicate of. – Bergi Nov 04 '15 at 22:35
  • @The Yes and yes. The code has been parsed (compiled as an analogy) but the function will be re referenced and assigned resources in order to hold closure variables. If run was not using the var test it would not make sense to include the prototype there. Using `this.run= func` will not put run on the prototype and is slower at creation time. But when calling run the `this.run` method has a 400% performance advantage over the `prototype.run`. "create many use few" use protoype.func, "create few use many" use this.func – Blindman67 Nov 04 '15 at 22:49
  • @Bergi Testing the performance of prototype show a significant advantage to avoiding prototype all together. Agreed prototypes closing over the last private is a catch, but when used wisely it provides a mechanism of sharing private properties between instances of the object. – Blindman67 Nov 04 '15 at 23:07