0

So let's say you have a really basic person object with two values and one function:

function personObject() {
    this.name = 'First Name';
    this.placeInLine = 1;
    this.setPlaceInLine = function(place) {
        this.placeInLine = place;
    }
}

And we setup some variables like this:

var john = new personObject();
var bill = new personObject();
var message = "";

Now look at the three codes snippets below...

---Code #1---

if(john.placeInLine < bill.placeInLine) message = "John is before Bill";
else message = "John is not before Bill";

RESULT: message = "John is not before Bill"; // because 1 is not less than 1

---Code #2---

bill.setPlaceInLine(2); // change Bill's place to 2 (instead of default of 1)
if(john.placeInLine < bill.placeInLine) message = "John is before Bill";
else message = "John is not before Bill";

RESULT: message = "John is before Bill"; // because 1 less than 2;

---Code #3---

if(john.placeInLine < bill.setPlaceInLine(2)) message = "John is before Bill";
else message = "John is not before Bill";

RESULT: message = "John is not before Bill": // why?

Is the .setPlaceInLine function being called after the comparison? Or is the act of running that function returning something that is then being compared to john.placeInLine?

double-beep
  • 5,031
  • 17
  • 33
  • 41

3 Answers3

8

Because setPlaceInLine method has no explicit return, and therefore returns undefined. And 1 < undefined evaluates to false: undefined gets converted to Number, giving NaN, and 1 < NaN is certainly false (1 > NaN is false too, btw).

While you can fix this by making your setter method return the assigned value:

PersonObject.prototype.setPlaceInLine = function(place) {
  return this.placeInLine = place;
}

... I think it's better (more clean) to use the setters and getters separately (like in your code #2 example).

As a sidenote, I'd recommend using prototypes to set up object methods (like I did in my example code). The reason for this is pretty well explained in this answer: basically with prototypes you will make just a single Function entity, used by all the created objects, when with this.someMethod you would create a new Function each time a constructor is called.

Community
  • 1
  • 1
raina77ow
  • 103,633
  • 15
  • 192
  • 229
  • Ah!!! Now I see. I tried a typeof on the bill.setPlaceInLine(2) call and it does return "undefined", which is what the comparison is using. Now I understand. Thank you for the clarification! – user1607577 Oct 22 '12 at 15:27
  • Quick question - my "person" object is just an example I made up...I'm actually calling a function on a object from another library. Is it a general standard to not have a return value on setters? Or was the library built poorly and it should have a return value? – user1607577 Oct 22 '12 at 15:28
  • 1
    @user1607577 most libraries return the object you are operating on, so that you can do chained operations like `bill.placeInLine().changeName("billl")` – Christoph Oct 22 '12 at 15:29
1

You are comparing to the returnvalue of the function.

Unless you actually return a value via return this.placeInLine; it will compare to the undefined always resulting in false.

Change your code to this:

this.setPlaceInLine = function(place) {
    return this.placeInLine = place;
}
Christoph
  • 50,121
  • 21
  • 99
  • 128
-1

setPlaceInLine returns nothing. And nothing is evaluated as less than 1. You could update setPlaceInLine to return the value:

function personObject() {
    this.name = 'First Name';
    this.placeInLine = 1;
    this.setPlaceInLine = function(place) {
        this.placeInLine = place;
        return place;
    }
}
MKS
  • 352
  • 3
  • 8