JS基礎(chǔ)知識(shí)知多少(二)--函數(shù)

通常來說产舞,一個(gè)函數(shù)就是一個(gè)可以被外部代碼調(diào)用(或函數(shù)本身遞歸調(diào)用)的“子程序”檬寂。和程序本身一樣,一個(gè)函數(shù)的函數(shù)體是由一系列的語句組成的势木。

1.函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別蛛倦?

syntax:
函數(shù)聲明:
<pre> function函數(shù)名稱(參數(shù):可選){函數(shù)體}</pre>
函數(shù)表達(dá)式:
<pre>functuion函數(shù)名稱(可選)(參數(shù):可選){函數(shù)體}</pre>
如果聲明了函數(shù)名稱的話,當(dāng)function 函數(shù)名稱(){}是作為賦值表達(dá)式的一部分的話啦桌,那它就是函數(shù)表達(dá)式溯壶;如果function函數(shù)名稱(){}被包含在一個(gè)函數(shù)體內(nèi),或者位于程序的最頂部的話甫男,那它就是一個(gè)函數(shù)聲明且改。
區(qū)別在于:
a.函數(shù)聲明會(huì)在任何表達(dá)式被解析和求值之前先被解析和求值,即使聲明在代碼的最后一行查剖,它也會(huì)在同作用域內(nèi)第一個(gè)表達(dá)式之前被解析/求值钾虐。示例:
<pre>
alert(fn());
function fn() {return 'Hello world!';}
</pre>
b.函數(shù)聲明在條件語句內(nèi)雖然可以用,但是沒有被標(biāo)準(zhǔn)化笋庄,也就是說不同的環(huán)境可能有不同的執(zhí)行結(jié)果效扫,所以這樣情況下,最好使用函數(shù)表達(dá)式:
c.函數(shù)聲明的syntax:
<pre>function 函數(shù)名(){}</pre>
函數(shù)表達(dá)式的syntax:
<pre>var 變量名=function 函數(shù)名(){};</pre>

函數(shù)聲明結(jié)尾沒有分號(hào)直砂,但是函數(shù)表達(dá)式以分號(hào)結(jié)尾菌仁。

2.什么是變量的聲明前置?什么是函數(shù)的聲明前置?
變量的聲明前置:JavaScript引擎的工作方式是静暂,先解析代碼济丘,獲取所有被聲明的變量,然后再一行一行地運(yùn)行洽蛀。這造成的結(jié)果就是所有的變量的聲明語句摹迷,都會(huì)被提升到代碼的頭部,也稱為變量提升郊供。
函數(shù)的聲明前置:函數(shù)聲明過程在整個(gè)程序執(zhí)行之前的預(yù)處理就完成了峡碉,所以只要在同一作用域,就可以訪問到驮审,即使在定義之前調(diào)用也可以鲫寄。

3.arguments 是什么 吉执?
arguments是一個(gè)類數(shù)組對(duì)象。代表傳給一個(gè)function的參數(shù)列表地来。是函數(shù)內(nèi)部的本地變量戳玫;arguments已經(jīng)不再是函數(shù)的屬性了∥窗撸可以在函數(shù)內(nèi)部通過使用arguments對(duì)象來獲取函數(shù)的所有參數(shù)咕宿。這個(gè)對(duì)象為傳遞給函數(shù)的每個(gè)參數(shù)簡(jiǎn)歷一個(gè)條目,條目的索引號(hào)從0開始颂碧。(MDN

4.函數(shù)的重載怎樣實(shí)現(xiàn)?
JavaScript沒有重載函數(shù)這個(gè)概念荠列,但是可以通過arguments來模擬函數(shù)重載。實(shí)現(xiàn)代碼示例:
<pre>
function sum(){
var sum=0;
for(var i=0;i < arguments.length;i++){
sum+=arguments[i];
}
return sum;
}
sum(1,2);
</pre>

5.立即執(zhí)行函數(shù)表達(dá)式是什么载城?有什么作用 肌似?

立即執(zhí)行函數(shù)表達(dá)式是函數(shù)定義完直接調(diào)用。
syntax:
<pre>a.(function(){/code/}());</pre>
<pre>b.(function(){/code/})();</pre>
<pre>c.!function(){/code/}();</pre>

作用:
a.js沒有塊級(jí)作用域诉瓦,用來隔離作用域避免污染川队,或者截?cái)嘧饔糜蜴湥苊忾]包造成引用常量無法釋放睬澡;
b.利用立即執(zhí)行特性固额,返回需要的業(yè)務(wù)函數(shù)或?qū)ο螅苊饷看瓮ㄟ^條件判斷來處理煞聪。

6.什么是函數(shù)的作用域鏈 ?
javascript中斗躏,變量的作用域有全局作用域和局部作用域兩種。
a.全局作用域:在代碼任何地方都能訪問到的對(duì)象擁有全局作用域
b.局部作用域:一般只在固定的代碼片段內(nèi)可以訪問到昔脯。
c.函數(shù)作用域鏈:在JavaScript中啄糙,函數(shù)也是對(duì)象,實(shí)際上云稚,JavaScript里一切都是對(duì)象隧饼。函數(shù)對(duì)象和其它對(duì)象一樣,擁有可以通過代碼訪問的屬性和一系列僅供JavaScript引擎訪問的內(nèi)部屬性静陈。其中一個(gè)內(nèi)部屬性是[[Scope]]燕雁,由ECMA-262標(biāo)準(zhǔn)第三版定義,該內(nèi)部屬性包含了函數(shù)被創(chuàng)建的作用域中對(duì)象的集合鲸拥,這個(gè)集合被稱為函數(shù)的作用域鏈拐格,它決定了哪些數(shù)據(jù)能被函數(shù)訪問。

代碼題:
1.以下代碼輸出什么刑赶?
<pre>
function getInfo(name, age, sex){
console.log('name:',name);
console.log('age:', age);
console.log('sex:', sex);
console.log(arguments);
arguments[0] = 'valley';
console.log('name', name);
}

getInfo('hunger', 28, '男');
getInfo('hunger', 28);
getInfo('男');
</pre>
輸出結(jié)果:
<pre>
getInfo('hunger', 28, '男');
name:hunger
age:28
sex:男
["hunger",28,"男"]
name valley
</pre>
<pre>
getInfo('hunger', 28);
name:hunger
age:28
sex:undefined
["hunger",28]
name valley
</pre>
<pre>
getInfo('男');
name:男
age:unfined
sex:unfined
["男"]
name valley
</pre>

2.寫一個(gè)函數(shù)禁荒,返回參數(shù)的平方和?
<pre>
function sumOfSquares(){
var sum=0;
for(var i=0;i < arguments.length;i++)
{
sum+=arguments[i]*arguments[i];
}
console.log(sum);
}
sumOfSquares(2,3,4); // 29
sumOfSquares(1,3); // 10
</pre>

3.如下代碼的輸出角撞?為什么 ?
<pre>
console.log(a); // undefined,變量提升
var a = 1;
console.log(b);//報(bào)錯(cuò)呛伴,b is not defined
</pre>

4.如下代碼的輸出?為什么 ?
<pre>
sayName('world'); //函數(shù)sayName聲明提前
sayAge(10); //函數(shù)sayAge聲明
function sayName(name){
console.log('hello ', name); //輸出:hello world
}
var sayAge = function(age){ //函數(shù)表達(dá)式
console.log(age); //報(bào)錯(cuò)谒所,sayAge is not a function.函數(shù)表達(dá)式的聲明不能提前
};
</pre>

5.如下代碼輸出热康?為什么?
<pre>
function fn(){}
var fn = 3;
console.log(fn);
</pre>

可以寫成:
<pre>
var fn;
function fn(){}
fn=3;
console.log(fn);
</pre>
輸出結(jié)果為:3劣领,var fn變量提升姐军,function fn(){}函數(shù)聲明前置,第三行代碼給fn賦值3尖淘,使其作為變量輸出奕锌。

6.如下代碼輸出?為什么
<pre>
function fn(fn2){
console.log(fn2);
var fn2 = 3;
console.log(fn2);
console.log(fn);
function fn2(){
console.log('fnnn2');
}
}
fn(10);
</pre>
<pre>
解析:
a.fn(10)調(diào)用函數(shù)function fn(fn2){}將10賦值給fn2;
b.由于函數(shù)聲明前置村生,console.log(fn2)輸出
function fn2(){
console.log('fnnn2');
}
c.var fn2=3給fn2重新賦值,console.log(fn2)輸出3惊暴;
d.console.log(fn)輸出:
function fn(fn2){
console.log(fn2);
var fn2=3;
console.log(fn2);
console.log(fn);
function fn2(){
console.log('fnnn2');
}
}
</pre>
7.如下代碼的輸出?為什么?
<pre>
var fn = 1;
function fn(fn){
console.log(fn);
}
console.log(fn(fn));
</pre>
輸出結(jié)果:
<pre>
代碼相當(dāng)于:
var fn;
function fn(fn){
console.log(fn);
}
fn=1;
console.log(fn(fn));
報(bào)錯(cuò):fn is not a function
原因是:變量聲明提前和函數(shù)聲明前置趁桃,但是function fn(fn){}的聲明在前面辽话,之后給變量賦值,變量賦值會(huì)覆蓋函數(shù)的聲明卫病,因此會(huì)報(bào)錯(cuò)油啤。
</pre>
8.如下代碼的輸出?為什么?
<pre>
//作用域
console.log(j);
console.log(i);
for(var i=0; i<10; i++){
var j = 100;
}
console.log(i);
console.log(j);
</pre>
輸出結(jié)果:
<pre>
console.log(i);//undefined,變量提升蟀苛,因?yàn)闆]有賦值益咬,所以輸出是undefined
console.log(j);//undefined,變量提升,因?yàn)闆]有賦值帜平,所以輸出是undefined
for(var i=0;i<10;i++){
var j=100;
}//定義全局變量i和j
console.log(i);//10
console.log(j);//100
結(jié)果為:
undefined
undefined
10
100
</pre>

9.如下代碼的輸出幽告?為什么 ?
<pre>
fn();
var i = 10;
var fn = 20;
console.log(i);
function fn(){
console.log(i);
var i = 99;
fn2();
console.log(i);
function fn2(){
i = 100;
}
}
</pre>
輸出結(jié)果:
<pre>
a.調(diào)用函數(shù)fn(){};
b.運(yùn)行函數(shù)fn(){};
function fn(){
var i;
console.log(i);//變量提升,變量聲明但沒有賦值罕模,輸出undefined
i = 99;
fn2(); //調(diào)用函數(shù)fn2()评腺,函數(shù)聲明前置
console.log(i);//輸出100
function fn2(){
i = 100;
}
}
c.var i=10;給i賦值10,覆蓋之前的100淑掌,console.log(i)輸出10
所以結(jié)果為:
undefined
100
10
</pre>
10.如下代碼的輸出蒿讥?為什么 ?
<pre>
var say = 0;
(function say(n){
console.log(n);
if(n<3) return;
say(n-1);
}( 10 ));
console.log(say);
</pre>
輸出結(jié)果:
<pre>
(function say(n){
console.log(n);
if(n<3) return;
say(n-1);
}( 10 ));為立即執(zhí)行表達(dá)式;
輸出結(jié)果為:
10
9
8
7
6
5
4
3
2
最后的console.log(say)輸出全局變量say:0
</pre>

參考文章:
1.湯姆大叔的博客
2.Back to Basics: JavaScript Hoisting
3.為什么要有js立即執(zhí)行函數(shù)抛腕,存在的意義是什么芋绸?
4.JavaScript作用域鏈

版權(quán)歸本人所有,若有轉(zhuǎn)載担敌,請(qǐng)注明來源

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末摔敛,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子全封,更是在濱河造成了極大的恐慌马昙,老刑警劉巖桃犬,帶你破解...
    沈念sama閱讀 222,104評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異行楞,居然都是意外死亡攒暇,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門子房,熙熙樓的掌柜王于貴愁眉苦臉地迎上來形用,“玉大人,你說我怎么就攤上這事证杭√锒龋” “怎么了?”我有些...
    開封第一講書人閱讀 168,697評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵解愤,是天一觀的道長(zhǎng)镇饺。 經(jīng)常有香客問我,道長(zhǎng)琢歇,這世上最難降的妖魔是什么兰怠? 我笑而不...
    開封第一講書人閱讀 59,836評(píng)論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮李茫,結(jié)果婚禮上揭保,老公的妹妹穿的比我還像新娘。我一直安慰自己魄宏,他們只是感情好秸侣,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著宠互,像睡著了一般味榛。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上予跌,一...
    開封第一講書人閱讀 52,441評(píng)論 1 310
  • 那天搏色,我揣著相機(jī)與錄音,去河邊找鬼券册。 笑死频轿,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的烁焙。 我是一名探鬼主播航邢,決...
    沈念sama閱讀 40,992評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼骄蝇!你這毒婦竟也來了膳殷?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,899評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤九火,失蹤者是張志新(化名)和其女友劉穎赚窃,沒想到半個(gè)月后册招,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,457評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡考榨,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評(píng)論 3 341
  • 正文 我和宋清朗相戀三年跨细,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片河质。...
    茶點(diǎn)故事閱讀 40,664評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖震叙,靈堂內(nèi)的尸體忽然破棺而出掀鹅,到底是詐尸還是另有隱情,我是刑警寧澤媒楼,帶...
    沈念sama閱讀 36,346評(píng)論 5 350
  • 正文 年R本政府宣布乐尊,位于F島的核電站,受9級(jí)特大地震影響划址,放射性物質(zhì)發(fā)生泄漏扔嵌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評(píng)論 3 334
  • 文/蒙蒙 一夺颤、第九天 我趴在偏房一處隱蔽的房頂上張望痢缎。 院中可真熱鬧,春花似錦世澜、人聲如沸独旷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嵌洼。三九已至,卻和暖如春封恰,著一層夾襖步出監(jiān)牢的瞬間麻养,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工诺舔, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留鳖昌,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,081評(píng)論 3 377
  • 正文 我出身青樓混萝,卻偏偏與公主長(zhǎng)得像遗遵,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子逸嘀,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 1. 函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別 (*) 函數(shù)在JS中有三種方式來定義:函數(shù)聲明(function decla...
    進(jìn)擊的阿群閱讀 445評(píng)論 0 1
  • 繼承 一车要、混入式繼承 二、原型繼承 利用原型中的成員可以被和其相關(guān)的對(duì)象共享這一特性崭倘,可以實(shí)現(xiàn)繼承翼岁,這種實(shí)現(xiàn)繼承的...
    magic_pill閱讀 1,064評(píng)論 0 3
  • 函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別 (*)解析器會(huì)率先讀取函數(shù)聲明类垫,并使其在執(zhí)行任何代碼之前可以訪問;函數(shù)表達(dá)式則必須...
    coolheadedY閱讀 390評(píng)論 0 1
  • 1. 有一天清早剛起床,電話鈴聲響起榆俺,拿起電話售躁,電話那頭說話,有氣無力茴晋,說一句停一下陪捷,聽了一會(huì)兒才知道,X姐...
    如果一切都可以閱讀 343評(píng)論 0 2
  • 開啟了塵封很久的上班模式诺擅,穿著標(biāo)準(zhǔn)正裝市袖,腳穿皮鞋,彰顯一身專業(yè)烁涌,重新回到了打工的地方苍碟,又開啟被公司“圈養(yǎng)”的時(shí)刻。...
    感受背影閱讀 187評(píng)論 0 0