-2

I want to have a prototype and call a static function. Here is my code:

function Client() {
    this.username = "username",
    this.password = "Password",
    this.printUsername = function() {
        this.username=$("#Username").val()
        console.log(this.username);
    };
};

Here is me calling it:

<button onclick="Client.printUsername()" type="button">Submit</button>

Here is the error in the console:

Uncaught TypeError: Object function Client() {
    this.username = "username",
    this.password = "Password",
    this.printUsername = function() {
        this.username=$("#Username").val()
        console.log(this.username);
    };
} has no method 'printUsername'

What is wrong with my code?

This still creates the error:

function Client() {
    this.username = "username",
    this.password = "Password",
    this.setUsername = function() {
        this.username=$("#Username").val()
        console.log(this.username);
    };
};

Client.prototype.printUsername = function() {
    this.username = $("#Username").val();
    console.log(this.username);
}
btf217
  • 51
  • 1
  • 2
  • 7
  • 3
    you must instantiate your `Client` – vsync Aug 05 '14 at 21:10
  • 4
    The simple fact of willing to print a username with a context inside a static function is a design flaw. – axelduch Aug 05 '14 at 21:13
  • The fact OP thinks he needs a static call is a design flaw imho. @OP do you realize what static means? – PeeHaa Aug 05 '14 at 21:13
  • OP, you need to rephrase your needs for us to be able to answer your question right. What do you exactly want to do with printUsername, and why should it be static ? – axelduch Aug 05 '14 at 21:16
  • possible duplicate of [class/static method in javascript?](http://stackoverflow.com/questions/7694501/class-static-method-in-javascript) – PeeHaa Aug 05 '14 at 21:17
  • @aduch I just found it hard to look elegant and call it in my button click method when it is not static – btf217 Aug 05 '14 at 21:32
  • @btf217 ok, I think I got it: on a page will there always be a single Client at most? – axelduch Aug 05 '14 at 21:34
  • @btf217 btw there is nothing wrong with using an instance method to print a user's name in your case – axelduch Aug 05 '14 at 21:37
  • @aduch Yes. I can make it not static also. Either option is fine. Is there an elegant way to do it non-static? – btf217 Aug 05 '14 at 21:39
  • @btf217 It's a bit confusing because your print function actually assigns a value to a member of the user, what is the main goal of your function here? – axelduch Aug 05 '14 at 21:44
  • @aduch Think of it as being called setUsername. I want to then log the result. – btf217 Aug 05 '14 at 21:45
  • JavaScript does not allow for "static" methods, no such construct exists in the prototype inheritance model. – Chris Pietschmann Aug 05 '14 at 22:20

3 Answers3

0

you must instantiate your Client like so:

var client = new Client();
// now you can do:
client.printUsername();

This enables the this inside your Client to reference the thing you actually want, because without the new.. thing above, the this will point to something else, the window object probably.

you could also use a prototype: (extending original Client)

Client.prototype.printUsername = function() {
    this.username = $("#Username").val();
    console.log(this.username);
};



Update - Showing all the code flow:

function Client(){
    this.username = "username";
    this.password = "Password";
};


Client.prototype.printUsername = function(){
    this.username = $("#Username").val();
    console.log(this.username);
};


var client = new Client();
// call it
client.printUsername();
vsync
  • 118,978
  • 58
  • 307
  • 400
  • Thanks but I want to avoid that. I want a static function. – btf217 Aug 05 '14 at 21:12
  • I don't get what you want here...sorry.. could you explain better? – vsync Aug 05 '14 at 21:13
  • I can make it non-static, but as a side note, that way of making it static does not work. Perhaps it needs to not contain "this" in the static method? I have posted in my original question my attempt at making it static that did not work. – btf217 Aug 05 '14 at 21:54
  • I don't understand why you chose another answer which came later, and is a copy of mine... this works 100%. I'll show you by giving you ALL the code, since you seem not to understand it. Also, I do not know the term "static function". never heard it in 10 years of intensive js coding. – vsync Aug 05 '14 at 22:07
  • You answer is not similar to the answer I accepted. Yours instantiates a new client meaning it is not static. Thanks for your help though. – btf217 Aug 06 '14 at 20:43
  • so maybe I don't understand the nature of your system. it is imperative to know what this `Client` represents and how the system works in order to model the code to best-fit. I gave my answer out of guessing how a general system with clients work. – vsync Aug 07 '14 at 10:05
0

Sorry I didn't feel like downloading jQuery just to test this. It works any way. The method is both static, and an instance method.

<html>
<body>
<input id="Username">
<button onclick="Client.printUsername()" type="button">Submit</button>
<script>
function Client() {
    this.username = "username",
    this.password = "Password",
    this.printUsername = function() {
        this.username=document.querySelector("#Username").value;
        console.log(this.username);
    };
};
var proto = Client.prototype;
Client.printUsername = function(){
    proto.username=document.querySelector("#Username").value;
    console.log(proto.username);
};
</script>
</body>
</html>

You can also do it like this.

<html>
<body>
<input id="Username">
<button onclick="Client.printUsername()" type="button">Submit</button>
<button onclick="new Client().printUsername2()" type="button">Submit</button>
<script>
function Client() {};

Client.prototype.username = "username";
Client.prototype.password = "Password";
Client.prototype.printUsername = function() {
    this.username=document.querySelector("#Username").value;
    console.log(this.username);
};
var proto = Client.prototype;
Client.printUsername = function(){
    proto.printUsername.call(proto);
};
Client.prototype.printUsername2 = function(){
    console.log(this.username);
};
</script>
</body>
</html>

The solution to instance properties being unique for the instance.

<html>
<body>
<input id="Username">
<button onclick="Client.printUsername()" type="button">Submit</button>
<button onclick="new Client().printUsername2()" type="button">Submit</button>
<script>
function Client() {
    //this.init can also be left outside the constructor if you want to choose
    //if properties change between instances, and call the init method directly.
    this.init.apply(this, arguments);
};
Client.prototype.init = function(){
    this.username = "username";
    this.password = "Password";
};
Client.prototype.username = "username";
Client.prototype.password = "Password";
Client.prototype.printUsername = function() {
    this.username=document.querySelector("#Username").value;
    console.log(this.username);
};
var proto = Client.prototype;
Client.printUsername = function(){
    proto.printUsername.call(proto);
};
Client.prototype.printUsername2 = function(){
    console.log(this.username);
};
</script>
</body>
</html>
Quentin Engles
  • 2,744
  • 1
  • 20
  • 33
  • Thanks it works. Finding it more elegant to delegate the method to event in html file using this technique but less elegant in the javascript, so will end up going for non-static – btf217 Aug 05 '14 at 21:58
  • Yep. It's really the only way to do it. Of course it depends on what you think is elegant. You should look at jQuery source. It does stuff like this quite often. – Quentin Engles Aug 05 '14 at 22:09
  • This answer shows lack of javascript knowledge, I'm sorry. This is not how prototyping should be done at all. `username` and `password` should **only** reside in the instance itself, NEVER in the prototype. also, your code is a mess. – vsync Aug 05 '14 at 22:10
  • @vsync No it doesn't. It answers the question. If you want instance username, and password then you can do it. There's nothing keeping any one from doing it. It depends on the use case. – Quentin Engles Aug 05 '14 at 22:12
  • @QuentinEngles - you instantiate `Client` because you have more than one, so, you absolutely musn't put username and password to be shared across ALL the clients' instances. that's absurd by any standards sir . your example won't ever work in real life, since password and username are never stored per-instance. – vsync Aug 05 '14 at 22:15
-2

Change the function to:

function Client() {
    this.username = "username",
    this.password = "Password",
};

Client.printUsername = function() {
    this.username=$("#Username").val()
    console.log(this.username);
};

That is the equivalent to a static function.

--EDIT--

Re-read the question and the code, this won't work as expected since this won't be available. Static functions don't have access to an instance which is why they are static.

HJ05
  • 1,358
  • 2
  • 11
  • 23
  • `this.username` is `undefined` inside Client.printUsername: it is not related to an instance. So `this` must not be used in this case – axelduch Aug 05 '14 at 21:12
  • Thanks @aduch I noticed that after I posted the answer. – HJ05 Aug 05 '14 at 21:13