函式宣告與函式表示式
從一個傻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,上面的語法是宣告,