5

If I have a variable named format and a method with the same name, how would I go about calling the variable, and the method?

use strict;

function Time() {
    this.format = 'x:y:z';
}

Time.prototype = {
    format: function (format) {

    }
}
Kid Diamond
  • 2,232
  • 8
  • 37
  • 79
  • you cannot - name them differently – Igor Apr 03 '15 at 16:23
  • Impossible. The method is overwritten. – theonlygusti Apr 03 '15 at 16:24
  • A better question would be for you to explain *why* you would need this behavior. You of course *can* write code wrongly, code that interferes with itself, but why would you? The code is simply written to fail. –  Apr 03 '15 at 16:41
  • @Jhawins This code was not written to fail. The reason why I wanted it like this was because I just couldn't think of a better names, and was wondering if it was possible in some kind of way. – Kid Diamond Apr 03 '15 at 16:43
  • @KidDiamond it's kind of like doing `foo = 9; (function() { var foo = 5; return foo; })()` and expecting to return 9. There's just no sense in it :P. There *is* a `foo` that is 9, but you won't be referencing it. –  Apr 03 '15 at 18:31
  • @Jhawins Might be, but when I logged the object in the console I saw that it both contained the variable **and** the function. So I thought there would be a way to call them regardless of the same name, – Kid Diamond Apr 03 '15 at 18:33

3 Answers3

7

You can't usually do this, because there is no difference in JavaScript between a method and a property containing a function -- they are exactly the same thing! You create methods by assigning functions to properties.

In this particular case, you can access the function object through the prototype and apply it to the object, but this is a terrible hack.

Time.prototype.format.apply(some_time_object);

You would be better off storing the method and the value in differently-named properties.

cdhowie
  • 158,093
  • 24
  • 286
  • 300
2

You cannot do this. The only property which will remain will be the string, the function will not exist in any instantiated objects.

Either name them differently, the method could be formatAs, or have a function with no arguments return the format:

function Time() {
  this.currentformat = 'x:y:z';
}

Time.prototype.format = function (format) {
  if (typeof format === "undefined"){
    return this.currentformat;
  }
  // ...
}
theonlygusti
  • 11,032
  • 11
  • 64
  • 119
  • I like the idea of a getter-setter function which gets the value if there is no parameter and sets it if there is one, but in this case I think his format() function returns the time according to said format, so it can't act as a getter. – Domino Apr 03 '15 at 16:32
  • @JacqueGoupil Yes it can. Why not? – theonlygusti Apr 03 '15 at 16:42
  • 1
    I think `instance.format()` is supposed to return `12:56:01`, so it can't also return `x:y:z`. But I might be misinterpreting what he's trying to do. – Domino Apr 03 '15 at 16:57
  • 1
    @JacqueGoupil Ah, makes sense; my first instinct was that it would set the format string to the argument, so `instance.format('x:z:y')` would change the `instance.format` property. Your way makes more sense, but then why is there an argument on the format method? – theonlygusti Apr 03 '15 at 17:00
1

Functions are actually objects stored in properties in JavaScript, so that's not possible.

When you call instance.format(), the interpreter looks at the instance to see if it has a property called format. If there is, it checks if it's a function and throws an error if it isn't. If the instance doesn't have such a property, it checks the instance's prototype and does the same thing, until an ancestor has a format property or until it reaches the top of the inheritance tree. In your situation, it will always try to execute the string, which will cause an error. The interpreter never looks at the prototype for its format() method.

You could rename the property to formatString or mask if you prefer.

Domino
  • 6,314
  • 1
  • 32
  • 58