1. 程式人生 > >函式宣告與函式表示式

函式宣告與函式表示式

從一個傻x問題開始……畫地為牢一下午,還是第二天才發現問題所在。下面把問題掛出來,大家引以為戒。

初學JavaScript的寶寶額,寫了一段想繞死我自己的程式,不要覺得怎麼這麼搞笑額 [ 翻白眼 ]

(function(){
  function fn(){
    document.write('1');
    setTimeout('fn()',3000);
  }
})()

fn函式為什麼不執行為什麼為什麼…呵呵,不呼叫怎麼執行!以上程式碼只是讓外層函式立即執行,fn()函式並沒有被呼叫。

將裡層函式fn()添小括號立即執行後,還出現了一個問題:setTimeout() 的第一個引數寫為程式碼串,即為 setTimeout(“fn()”,3000) 形式時會出錯,改為 setTimeout( fn, 3000) 會正確執行。setTimeout()方法的第一個引數可以是程式碼串,仿照setTimeout("alert('out!')",3000),寫了第一種形式,但有錯誤額…這是什麼原因?待我慢慢道來。

javascript中函式定義有兩種方式。

1. 函式宣告

形式為 function fn( ) { },ECMAScript規範規定函式宣告必須始終帶有一個識別符號,也就是我們常說的函式名,即這裡的fn。

函式名在自身作用域和父作用域內是可獲取的。

就像變數宣告必須以“var”開頭一樣,函式宣告必須以“function”開頭。

函式宣告只能以fn( )形式呼叫。

2. 函式表示式

形式通常為var fn = function( ){ },函式定義為表示式語句的一部分,通常是變數賦值的形式。

函式定義部分可以是匿名的,也可以是命名的,但此時函式名在作用域外是不可獲取的。

函式表示式不能以“function開頭”

所以下面例子中最後一個匿名錶達式要用小括號將其括起來。這點,另一篇關於立即執行的筆記中有說明噢。

函式表示式可以後面加括號立即呼叫該函式,而函式宣告不可以。

匿名函式屬於函式表示式。然後就出現了以下各種形式。

//annoymous function expression
var fn = function(){
  return 3;
}

//named function expression
var fn = function a(){
  return 3;
}

//self invoking function expression
(function sayHello(){
  alert('hello!');
})();                 //這裡加小括號立即執行,是因為這是一個函式表示式。sayHello看起來像是一個函式宣告,實則因為加了括號,不再以function開頭,變為表示式。

關於函式宣告和函式表示式二者的區別,除了上面列出的各種外,還有一個函式提升的問題,這裡就不多講啦。


回到最初的問題,現在將程式碼改為如下。

(function (){
  function fn(){
    document.write('1');
    setTimeout('fn()',3000);
  }
  fn();
})();

將外層函式剝掉顯得更直觀,當初出錯就是因為受外層函式的影響。現在程式碼如下。

(function fn(){
    document.write('1');
    setTimeout('fn()',3000);
})();

問題來了……此時仍然不能執行,報錯 fn is not defined……

我嘗試修改為以下兩種形式,都能正確執行。

(function fn(){
    document.write('1');
    setTimeout(fn,3000);
})();
function fn(){
    document.write('1');
    setTimeout('fn()',3000);
}
fn();

嘗試解讀……歡迎批評指正。

首先,修改後的第一種寫法傳遞的是Function,它會從當前作用域向上查詢,直到找到fn。實名函式可以在自身作用域中呼叫自己,就是這個道理。而且此時fn變數實際指向了一個記憶體地址。

而最開始的字串寫法僅僅是個字串,按值傳遞,下次呼叫或者執行時記憶體在哪裡已經不確定了,所以找不到作用域。此時只能在全域性中查詢,而恰巧定義的fn函式並不在全域性中。當fn()函式被括號包裹立即執行時,已經形成了一個私有作用域,fn只在該私有域下存在,所以會報錯“fn沒有被定義”。

那修改後的第二種寫法也是字串形式,為什麼就可以了呢?因為此時只在全域性中查詢!修改後的fn()是在全域性中定義的。

這與之前理解的setTimeout是一個Window物件方法無關,不管setTimeout是什麼的方法,只要能訪問到引數函式就能執行。

以下是之前理解的,有誤,勿參考!!

【首先setTimeout是一個window物件方法,當第一個引數寫為'fn()'字串形式時,其實執行的是window.fn()。當fn()函式被括號包裹立即執行時,已經形成了一個私有作用域,fn只在該私有域下存在,在全域性內不存在,所以會報錯“fn沒有被定義”。】

相關推薦

JS函式宣告函式表示式的區別

函式宣告與函式表示式的區別 前面我們已經說了兩種定義函式的方式:函式宣告與函式表示式。那麼這兩種方式有區別嗎,還是一樣的呢?下面我們來進一步探討探討。 下面我們定義了兩個函式分別為 hello 和 hi,前者採用函式宣告,後者採用函式表示式,然後再呼叫,如下: func

JavaScript函式宣告函式表示式的區別

函式宣告與函式表示式的區別 函式宣告與函式表示式定義函式看似相同,實際上在解析器向執行環境中載入資料時,解析器會率先讀取函式宣告,並使其在執行任何程式碼之前可用(可以訪問);至於函式表示式,則必須等到解析器執行到他所在的程式碼行,才會真正被解釋執行。 換句話說,就是通過函式宣告定義的

JS中函式宣告函式表示式的不同

Js中的函式宣告是指下面的形式:       function functionName(){ }  這樣的方式來宣告一個函式,而函式表示式則是類似表示式那樣來宣告一個函式,如:        var functionName = function(){ }  可能很多

匿名具名函式函式宣告函式表示式、立即執行函式(已完結)

匿名與具名函式 這屬於常識性問題,但是還是有必要說說 沒有函式名的函式就叫匿名函式,有函式名的函式就叫具名函式 setInterval(function(){//匿名函式 ... },1000); va

[ javascript ] javascript 函式宣告函式表示式的區別

還是一樣,先上程式碼: <script> var f = function g() { return 1; }; if (false) { f = function g(){ return 2;

JS-函式宣告函式表示式的區別

定義: 1 函式宣告:function foo(){} 2 函式表示式: var bar=function foo(){} 區別: 1 函式宣告會在任何表示式被解析和求值之前先行被解析和求值。即使宣告位於原始碼中的最後一行,它也會先

函式宣告函式表示式以及立即執行函式的討論

函式宣告的定義:function fn(){……},使用function關鍵字宣告一個函式,再指定一個函式名,叫函式宣告。 函式表示式:var fn=function(){……},使用function關鍵字宣告一個函式,但未給函式命名,最後將匿名函式賦予一個變數,叫函式表示

JavaScript中函式宣告函式表示式區別

眾所周知,JavaScript中宣告函式可以用函式宣告形式,也可以用函式表示式形式。本文介紹一下兩者區別。 函式宣告: alert(sum(10,10)); function sum(num1,num2){ return num1 +num2; } 以上程式碼

javascript 函式宣告函式表示式的區別

還是一樣,先上程式碼: <script> var f = function g() { return 1; }; if (false) { f = function g(){ return 2;

js中函式宣告函式表示式以及匿名函式的理解

在JS的學習中遇到一些JS函式宣告的問題,找了一些資料學習之後,有了自己的一些初步的認識。 首先,瞭解函式宣告,函式宣告:就是使用關鍵字function,與指定的某個欄位組成函式,作為函式宣告。例如: function funName(){ // }這就是簡單的函式函式聲明瞭。 接下來就是函式表示式,函

函式宣告函式表示式

從一個傻x問題開始……畫地為牢一下午,還是第二天才發現問題所在。下面把問題掛出來,大家引以為戒。 初學JavaScript的寶寶額,寫了一段想繞死我自己的程式,不要覺得怎麼這麼搞笑額 [ 翻白眼 ] (function(){ function fn(){ do

函式宣告的幾種方式,函式宣告函式表示式的區別,函式呼叫的幾種方式

函式宣告的幾種方式 三種 : 函式宣告(1),函式表示式(2~5),Function構造器(6) 1.function func1(a){}//函式宣告 2.var func2=function(b){}//函式表示式 3.var func3=function func4(

函式宣告函式表示式基礎介紹

函式宣告: function a(){ alert(1); } 函式表示式: 匿名:var a=function(){alert(1);}; 命名:var a=function fn(){alert(1);}; 函式宣告轉化成函式表示式:加()、~

函式宣告函式表示式不同2

  Javascript Function無處不在,而且功能強大!通過Javascript函式可以讓JS具有面向物件的一些特徵,實現封裝、繼承等,也可以讓程式碼得到複用。但事物都有兩面性,Javascript函式有的時候也比較“任性”,你如果不瞭解它的“性情”,它很可能給你製造出一些意想不到的麻煩(bugs)

JavaScript: 函式宣告函式表示式

//函式宣告 var functionOne =function(){ //code.... } //函式表示式 function functionTwo(){ //code.... } 在JS中, 這兩個不同方式來定義function時

簡析JavaScript中的Function型別(二)——函式宣告函式表示式的區別

開發十年,就只剩下這套架構體系了! >>>   

javascript立即執行函式函式宣告函式表示式

javascript和其他程式語言相比比較隨意,所以javascript程式碼中充滿各種奇葩的寫法,有時霧裡看花,當然,能理解各型各色的寫法也是對javascript語言特性更進一步的深入理解。( function(){…} )()和( function (){…} () )

eval及函式宣告函式表示式

1,eval:將一個物件行使額字串轉換為物件 { name: 'Jim' ,age :19}==>語法錯誤 //使用()將其轉化成表示式,{}不再是語句塊了,就是物件了 ->var o= eval( "( { name : 'Jim' ,age :19 } )"} //在js中有

函式宣告函式表示式、立即執行函式、你不知道的javascript

#你不知道的javascript上卷(2)# 1、函式宣告、函式表示式 // 例子一 函式宣告 function foo () { var a = 3 console.log(a) // 3 } foo () // 例子二 函式表示式 (function foo () {

JS-函式宣告函式表示式

    問題:       1, function foo() {};            2, var foo = function () {};   1,上面的語法是宣告,