1

I have the following code in document.ready()

if ($("#site-master").length > 0) {

    setMinContentHeight();

    function setMinContentHeight() {

        // removed for clarity
    }
}

I simply check if the page is correct (#site-master), then call my minimum height function, however I'm getting the following error in firebug: ReferenceError: setMinContentHeight is not defined.

I'm no javascript expert, but how can this be? The function works if I move it outside of document.ready(). I have checked and the code inside the if statement is reached.

Also, is this the best way of achieving what I want?

Thanks in advance.

dotnetnoob
  • 9,233
  • 17
  • 51
  • 92

5 Answers5

10

Never declare your functions inside if or for statements:

function setMinContentHeight() {
    // removed for clarity
}

if ($("#site-master").length > 0) {
    setMinContentHeight();
}

If we address the ECMAScript specification, according to Chapter 12, if clause is considered to be a Statement (as well as for, while, with, try/catch, etc).

Hence, following the NOTE from Semantics section:

Several widely used implementations of ECMAScript are known to support the use of FunctionDeclaration as a Statement. However there are significant and irreconcilable variations among the implementations in the semantics applied to such FunctionDeclarations. Because of these irreconcilable differences, the use of a FunctionDeclaration as a Statement results in code that is not reliably portable among implementations. It is recommended that ECMAScript implementations either disallow this usage of FunctionDeclaration or issue a warning when such a usage is encountered. Future editions of ECMAScript may define alternative portable means for declaring functions in a Statement context.

It means that we cannot guarantee the consistent behavior in such cases, and, as a result, we will always get exception in strict mode in case if function was declared inside the statement.

VisioN
  • 132,029
  • 27
  • 254
  • 262
  • @dystroy Is it the best of the worst? :) – VisioN Mar 22 '13 at 14:53
  • No, it's right. You could precise that browsers handle function declared in conditioned blocks in different ways. And an ecmascript reference would probably bring more rep. – Denys Séguret Mar 22 '13 at 14:54
  • @dystroy: It's not explicitly mentioned in the spec. You can just point to the production of [`SourceElement`](http://es5.github.com/#x14) – Bergi Mar 22 '13 at 15:03
  • 1
    @Bergi Well, there is some sort of note in Chapter 12. I have added the note to the answer. – VisioN Mar 22 '13 at 15:17
  • 1
    Thanks for adding the notes about *FunctionDeclaration* vs *Statement* and the incompatible syntax extensions in various browsers. It is a useful lesson! – dsh Mar 22 '13 at 16:35
4

First, read on the difference between var functionName = function() {} and function functionName() {} to understand function declarations vs expressions. Now what do you have? Nothing of the two, since function declarations need to be on the top level of function/script code - nesting them in blocks is not allowed. It's called a function statement, is nonstandard and working differently.

Put it outside the if-block:

// here
if ($("#site-master").length > 0) {
    setMinContentHeight();
}
// or here:
function setMinContentHeight() {
    …
}
Community
  • 1
  • 1
Bergi
  • 513,640
  • 108
  • 821
  • 1,164
3
if ($("#site-master").length > 0) {
    setMinContentHeight();
}
function setMinContentHeight() {
        // removed for clarity
}

You need to declare your function in the global scope.

Brad M
  • 7,689
  • 1
  • 19
  • 37
2

Place the call after you've defined the function and don't define functions inside an if block:

function setMinContentHeight() {
    // removed for clarity
}

if ($("#site-master").length > 0) {
    setMinContentHeight();
}
dsgriffin
  • 61,907
  • 17
  • 128
  • 134
0

Maybe you have problems with browser compatibility, but it works like this:

right:

n();
function n(){ alert('1'); }

wrong:

n();
var n = function(){ alert('1'); }
karaxuna
  • 25,822
  • 11
  • 76
  • 111