[英]Ambiguous function declaration in Javascript
我是Javascript的新手,並對函數聲明的工作方式感到困惑。 我對此做了一些測試並獲得了一些有趣的結果:
say();
function say()
{
alert("say");
}
前進聲明工作和彈出“說”
相反
say();
say = function()
{
alert("say");
}
沒有工作,雖然它也聲明了一個函數對象
如果我們聲明該函數並在之后重新聲明:
function say()
{
alert("speak");
}
say();
function say()
{
alert("say");
}
我得到“說”而不是“說話”。 這太令人驚訝了!
好。 似乎只有最新的函數聲明才有效。 然后讓我們首先聲明函數對象,然后是“常規”函數:
say = function()
{
alert("speak");
}
say();
function say()
{
alert("say");
}
say();
另一個驚喜,是“說話”,然后是“說話”。 “常規”功能聲明根本不起作用!
是否有所有這些的解釋? 並且,如果“常規”函數聲明真的是“脆弱的”並且可以通過具有相同名稱的函數對象輕松覆蓋,那么我應該遠離它嗎?
另一個問題是:只使用函數對象格式,前向聲明是否變得不可能? 有沒有辦法在Javascript中“模擬”它?
Javascript的工作方式如下:
解析文檔,並在執行實際語句之前立即考慮function
聲明。 這解釋了你的第一個例子。
如果將函數分配給局部變量,則在執行期間完成,因此您無法在第二個示例中使用該方法。
您所經歷的是,如果您聲明一個函數兩次,則最后一個函數將由整個應用程序使用。 那是你的第三個例子。
這些函數是window
對象的成員,它們實際上是全局聲明的。 如果將局部變量分配給函數的值,則該局部變量優先於window
對象中的成員。 如果javascript找不到局部變量,它會在范圍內搜索以找到它, window
對象是最后的手段。 這是您的最后一個例子發生了什么,它有一個可變的say
是在一個更具體的范圍比全局函數say
。
如果你想重新聲明say
在運行時,即在交換你的最后一個例子聲明的順序,那么你會看到你所期望的兩種不同的警報:
say(); //speak, the global function
function say() {
alert('speak');
}
var say = function() {
alert('say');
}
say(); //say, the declared local variable
say();
function say()
{
alert("say");
}
這里解釋器在調用時獲取say()
的定義並執行它。
say();
say = function()
{
alert("say");
}
這里沒有定義say()
來獲取 - 而是將一個匿名函數賦給變量。 解釋器無法“找到”它,就像它可以找到前向聲明一樣。
function say()
{
alert("speak");
}
say();
function say()
{
alert("say");
}
這里say
定義然后重新定義 - 最后一個定義勝出。
say = function()
{
alert("speak");
}
say();
function say()
{
alert("say");
}
say();
這里say
是一個指向匿名函數的變量(在解釋第一個語句之后)。 這優先於任何函數定義,就像在賦值之前放置函數定義一樣。
但如果你有
say();
say = function()
{
alert("speak");
}
say();
function say()
{
alert("say");
}
然后你會得到“說”然后“說”。
您可以期望按順序應用函數定義。 然后將按順序執行所有非方法代碼行,包括函數對象的賦值。 這解釋了您的每個示例。 這是一個有趣的問題。 在嘗試調用它之后,你真的無法分配一個函數對象,並期望它能夠工作。 但是,實際上將首先應用遵循可執行代碼的函數定義。
它總是好主意稍后調用該函數,即使javascript的工作方式如此。
大多數語言不會以這種方式工作,而是這樣做。
function say(){
alert("say");
}
say();
要么
say = function(){
alert("say");
}
say();
要么
(function(){
alert("say");
})();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.