11

If I execute the test function in the following code fragment:

function pointInside( r, p ) {
    var result =
        ( p.x >= r.location.x - r.size.width * 0.5 ) &&
        ( p.x <= r.location.x + r.size.width * 0.5 ) &&
        ( p.y >= r.location.y - r.size.height * 0.5 ) &&
        ( p.y <= r.location.y + r.size.height * 0.5 )
    ;
    return result;
}

function test() {
    var rect = {};
    rect["location"] = { x:6, y:5 };
    rect["size"] = { width:10, height:8 };
    var p = { x:10, y:8 };
    var inside = pointInside( rect, p );
    console.log( inside ? "inside" : "outside" );
}

then the text "inside" gets written to the console. Great. Now, if I change the pointInside function to this:

function pointInside( r, p ) {
    return
        ( p.x >= r.location.x - r.size.width * 0.5 ) &&
        ( p.x <= r.location.x + r.size.width * 0.5 ) &&
        ( p.y >= r.location.y - r.size.height * 0.5 ) &&
        ( p.y <= r.location.y + r.size.height * 0.5 )
    ;
}

then when I call the test function "outside" gets written to the console. On further investigation I find that the pointInside function is actually returning undefined. Why? I can't see any meaningful difference between the two versions of pointInside. Can anyone explain this to me?

2 Answers2

11

In javascript, ; is optional (at end of statement) ... so your function returns 'undefined' (which is false-y) and the rest of the code in that function is effectively ignored ... wonderful isn't it!!

try the following

function pointInside( r, p ) {
    return (
        ( p.x >= r.location.x - r.size.width * 0.5 ) &&
        ( p.x <= r.location.x + r.size.width * 0.5 ) &&
        ( p.y >= r.location.y - r.size.height * 0.5 ) &&
        ( p.y <= r.location.y + r.size.height * 0.5 )
    );
}

it's something that will probably never be fixed, this stupid behaviour, because it would break too much (poor) code

Jaromanda X
  • 53,868
  • 5
  • 73
  • 87
8

Unfortunately many javascript interpreters try to be forgiving about missing semicolons. If you have "return" and then an end of line, many interpreters will assume that you have forgotten a semicolon. Hence your "undefined".

Max Murphy
  • 1,701
  • 1
  • 19
  • 29
  • Whilst I don't agree with a lot of the details, the general feeling is about accurate: https://www.youtube.com/watch?v=D5xh0ZIEUOE – Max Murphy Aug 02 '15 at 11:48
  • 6
    This is part of the spec, it's not something that "many interpreters try to do", it's something that *all* interpreters *must* do. – Jörg W Mittag Aug 02 '15 at 13:24
  • Perhaps they must, but as is often the case reality and standards don't always intersect. I'm using tiny-js at the moment, an embedded interpreter for microcontrollers. There return waits for a semicolon, so it's not standards compliant in that respect. Not dealing with weird rules might not be compliant but it keeps the code small and easy to validate for security issues. – Max Murphy Aug 02 '15 at 14:28