2012-04-02 103 views
17

如果我跑定義之前,下面的功能,我會得到這個錯誤...在調用它之前是否需要定義一個Javascript函數?

Uncaught ReferenceError: openModal is not defined 

運行,然後定義

$(document).ready(function() { 

    delay(openModal, 2000); 

    delay = function (f, t) { 
     setTimeout(function() { 
      f(); 
     }, t); 
    }; 

    openModal = function() { 
     $('#modal-box').css({ 
      left: $(window).width()/2 - $('#modal-box').width()/2, 
      top: $(window).height()/2 - $('#modal-box').height()/2 
     }); 
     $('#modal-box').show(); 
     $('#modal-mask').show(); 
    }; 

}); 

現在,如果我先定義函數,然後調用它,它的工作原理...我在PHP中有一個背景,所以我習慣於能夠全局訪問函數,我是否做錯了什麼,或者在使用之前必須定義所有函數?

$(document).ready(function() { 

    delay = function (f, t) { 
     setTimeout(function() { 
      f(); 
     }, t); 
    }; 

    openModal = function() { 
     $('#modal-box').css({ 
      left: $(window).width()/2 - $('#modal-box').width()/2, 
      top: $(window).height()/2 - $('#modal-box').height()/2 
     }); 
     $('#modal-box').show(); 
     $('#modal-mask').show(); 
    }; 

    delay(openModal, 2000); 

}); 
+0

是一切,即你聲明的標識符'openModal'(而不是限定它)上面範圍?例如'var openModal;' – Rup 2012-04-02 08:59:04

+2

相關:http://stackoverflow.com/questions/261599/why-can-i-use-a-function-before-its-defined-in-javascript – TJHeuvel 2012-04-02 08:59:12

+0

@Rup這是第一次openModal被使用 – JasonDavis 2012-04-02 08:59:55

回答

32

當你將一個函數的變量,您必須先指定它,然後才能使用該變量來訪問該函數。

如果你聲明與常規語法,而不是將其分配給一個變量的函數,當代碼解析它的定義,所以此工程:

$(document).ready(function() { 

    delay(openModal, 2000); 

    function openModal() { 
     $('#modal-box').css({ 
      left: $(window).width()/2 - $('#modal-box').width()/2, 
      top: $(window).height()/2 - $('#modal-box').height()/2 
     }); 
     $('#modal-box').show(); 
     $('#modal-mask').show(); 
    }; 

}); 

(注意:在範圍上的差異,但如果你。創建變量openModal只是使用它隱式地創建,它將在全局範圍內創建並且可供所有代碼使用。在另一個函數內部聲明函數時,它只會在該函數內部提供。變量本地的功能也使用var openModal = function() {。)

6

將函數定義移動到document.ready塊之外,並且事情將按預期工作。在javascript中(與大多數語言一樣),您必須在對其進行引用之前定義一個函數或變量。

在第一個示例中,您在delay()的調用中引用openModal,但javascript無法知道openModal是什麼。

openModal = function() { 
    $('#modal-box').css({ 
     left: $(window).width()/2 - $('#modal-box').width()/2, 
     top: $(window).height()/2 - $('#modal-box').height()/2 
    }); 
    $('#modal-box').show(); 
    $('#modal-mask').show(); 
}; 

$(document).ready(function() { 
    delay(openModal, 2000); 
}); 

編輯:

TJHeuvel指出function做一些掛羊頭賣狗肉定義函數之前,什麼都在同一塊被執行: Why can I use a function before it's defined in Javascript?

+4

定義外部功能的要點是什麼? *「您必須先定義一個函數,然後再參考它」*:不一定。由於函數*聲明*被掛起,你可以在任何地方定義它們,當前作用域中的其他代碼可以調用它。只有函數*表達式*可以在分配後調用。 – 2012-04-02 09:04:57

+0

請注意,當您將函數分配給變量時,TJHevel指出的內容不適用。即使函數對象本身是在解析代碼時創建的,它也會在運行時分配給變量。 – Guffa 2012-04-02 09:13:56

-1

在shor牛逼是你必須使用一個函數之前定義它,但你可以使用你的延遲的setTimeout函數,它接受一個字符串作爲代碼exectute:

$(document).ready(function() { 

    setTimeOut('openModal()', 2000); 

    openModal = function() { 
     $('#modal-box').css({ 
      left: $(window).width()/2 - $('#modal-box').width()/2, 
      top: $(window).height()/2 - $('#modal-box').height()/2 
     }); 
     $('#modal-box').show(); 
     $('#modal-mask').show(); 
    }; 

}); 

這會工作作爲函數不叫,直到在它被定義之後。

+2

您的第一個建議不起作用,因爲在您調用'delay(openModal,2000)'的那一刻,'openModal'仍然持有對空函數的引用。實際功能只在之後分配,但不影響您已經通過的值。你的第二個建議只能「錯誤地」起作用。由於'openModal'沒有用'var'聲明,它是全局的。但是,只要你用'var'正確地聲明瞭它,它就不會工作了,因爲'setTimeout'在全局作用域中評估字符串(並且'openModal'對於就緒事件處理程序是本地的)。 – 2012-04-02 09:06:36

+0

好的謝謝。編輯 – Richard 2012-04-02 09:08:43

1

我會說,是的。在調用之前,必須定義一個函數。 但有些函數可以被調用(調用)已經被定義之前,他們(吊)

兩種不同類型的功能,我想寫的是:

表達功能&減速功能

1 - 表達式函數:函數表達式可以存儲在一個變量中,因此它們不需要函數名。它們也將被命名爲匿名函數(一個沒有名字的函數)。調用(調用)它們總是需要使用變量名稱。如果調用之前調用了這些函數,則這些函數將不起作用,這意味着這裏不會出現「提升」。我們總是必須首先定義表達式函數,然後調用它。

let lastName = function (family) { 
console.log("My last name is " + family); 
};   
let x = lastName("Lopez"); 

這是你如何在ES6寫:

lastName = (family) => console.log("My last name is " + family); 
x = lastName("Lopez"); 

2-減速功能:函數聲明的語法如下不立即執行。它們被「保存以供以後使用」,並且當它們被調用(調用)時將在稍後被執行。如果在它們被定義之前或之後調用它們,則這些類型的函數起作用。如果在定義之前調用減速功能 - 起升 - 正常工作。

function Name(name) { 
    console.log("My cat's name is " + name); 
} 
Name("Chloe"); 

吊裝例如:

Name("Chloe"); 
function Name(name) { 
    console.log("My cat's name is " + name); 
} 
相關問題