函數(shù)

一莫其、問答

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

Js中的函數(shù)聲明是指下面的形式:

function functionName() {
  alert("Hello");
}

函數(shù)表達(dá)式則是類似表達(dá)式那樣來聲明一個(gè)函數(shù)颂砸,如:

var functionName = function() {
  alert("Hello");
}
functionName();

js的解析器對函數(shù)聲明與函數(shù)表達(dá)式并不是一視同仁地對待的夸浅。
對于函數(shù)聲明,js解析器會優(yōu)先讀取朴则,確保在所有代碼執(zhí)行之前聲明已經(jīng)被解析;
而函數(shù)表達(dá)式匙赞,如同定義其它基本類型的變量一樣佛掖,只在執(zhí)行到某一句時(shí)也會對其進(jìn)行解析。
所以在實(shí)際中涌庭,它們還是會有差異的芥被,具體表現(xiàn)在,當(dāng)使用函數(shù)聲明的形式來定義函數(shù)時(shí)坐榆,可將調(diào)用語句寫在函數(shù)聲明之前拴魄,而后者,這樣做的話會報(bào)錯(cuò)席镀。

什么是變量的聲明前置匹中?什么是函數(shù)的聲明前置?

變量聲明前置:javascript的變量聲明具有hoisting機(jī)制豪诲,JavaScript引擎在執(zhí)行的時(shí)候顶捷,只要變量在代碼中進(jìn)行了聲明,無論它在哪個(gè)位置上進(jìn)行聲明屎篱, js引擎都會將它的聲明放在范圍作用域的頂部服赎。

console.log(a); //這個(gè)時(shí)候的輸出結(jié)果為undefined,因?yàn)槁暶鞅磺爸昧怂圆粫?bào)錯(cuò)
var a = 1;

/*等同于:*/

var a;
console.log(a);
a = 1;

函數(shù)聲明前置:和變量聲明前置一樣交播,因hoisting機(jī)制重虑,執(zhí)行代碼之前會先讀取函數(shù)聲明,只要函數(shù)在代碼中進(jìn)行了聲明秦士,無論它在哪個(gè)位置上進(jìn)行聲明缺厉, js引擎都會將它的聲明放在范圍作用域的頂部。意味著可以把函數(shù)申明放在調(diào)用它的語句后面隧土,但是函數(shù)表達(dá)式不行提针。

sayHi(); //此處輸出結(jié)果“hi”,因?yàn)楹瘮?shù)生命被前置了所以能正常調(diào)用
sayName(); //報(bào)錯(cuò)次洼。僅僅是表達(dá)式里的變量sayName被前置了关贵,此時(shí)未解析到函數(shù)
function sayHi() {
  console.log("hi");
}

var sayName = function() {
  console.log("Amy");
}

arguments 是什么?

arguments 是是JavaScript里的一個(gè)內(nèi)置對象卖毁,所有的函數(shù)都有屬于自己的一個(gè)arguments對象揖曾,它包括了函所有調(diào)用的參數(shù),條目索引從 0 開始亥啦。他不是一個(gè)數(shù)組炭剪,如果用typeof arguments,返回的是'object'翔脱。

function myArray() {
  console.log(arguments[2]); //輸出30
}
myArray(10,20,30);
函數(shù)的重載怎樣實(shí)現(xiàn)奴拦?

JS函數(shù)沒有重載這個(gè)概念,相同函數(shù)重復(fù)聲明時(shí)届吁,后面覆蓋前面的错妖。
但每一個(gè)函數(shù)都有一個(gè)特殊的參數(shù)arguments绿鸣,可以通過它傳遞參數(shù)個(gè)數(shù)來實(shí)現(xiàn)不同效果。

<script type="text/javascript">
function add() {
    if (arguments.length == 1) {
        alert(arguments[0] + 10);
    }
    else if (arguments.length == 2) {
        alert(arguments[0] + arguments[1]);
    }
}
//函數(shù)調(diào)用
add(10);
add(10, 20);
</script>
立即執(zhí)行函數(shù)表達(dá)式是什么暂氯?有什么作用潮模?
//方法一:
(function myFunction() {
}()
)

//方法二:
(function myFunction() {
}
)()

用立即執(zhí)行函數(shù)處理模塊化可以減少全局變量造成的空間污染,構(gòu)造更多的私有變量痴施。

什么是函數(shù)的作用域鏈擎厢?

任何程序設(shè)計(jì)語言都有作用域的概念,簡單的說辣吃,作用域就是變量與函數(shù)的可訪問范圍动遭,即作用域控制著變量與函數(shù)的可見性和生命周期。在JavaScript中神得,變量的作用域有全局作用域和局部作用域兩種厘惦。

全局作用域:在代碼中任何地方都能訪問到的對象擁有全局作用域。

  • 最外層函數(shù)和在最外層函數(shù)外面定義的變量擁有全局作用域循头;
  • 所有末定義直接賦值的變量自動聲明為擁有全局作用域绵估;
  • 所有window對象的屬性擁有全局作用域,例如:window.name卡骂、window.location国裳、window.top等等。

局部作用域:和全局作用域相反全跨,局部作用域一般只在固定的代碼片段內(nèi)可訪問到缝左,最常見的例如函數(shù)內(nèi)部,所以在一些地方也會看到有人把這種作用域稱為函數(shù)作用域浓若。

當(dāng)代碼在一個(gè)環(huán)境中執(zhí)行時(shí)渺杉,會創(chuàng)建變量對象的的一個(gè)作用域鏈(scope chain)。作用域鏈的用途挪钓,是保證對執(zhí)行環(huán)境有權(quán)訪問的所有變量和函數(shù)的有序訪問是越。作用域鏈的前端,始終都是當(dāng)前執(zhí)行的代碼所在環(huán)境的變量對象碌上。如果這個(gè)環(huán)境是一個(gè)函數(shù)倚评,則將其活動對象作為變量對象。
每一個(gè)函數(shù)都有自己的執(zhí)行環(huán)境馏予,當(dāng)執(zhí)行流進(jìn)一個(gè)函數(shù)時(shí)天梧,函數(shù)環(huán)境就會被推入一個(gè)環(huán)境棧中,而在函數(shù)執(zhí)行之后霞丧,棧將其環(huán)境彈出呢岗,把控制權(quán)返回給之前的執(zhí)行環(huán)境,這個(gè)棧也就是作用域鏈

參考

二后豫、代碼

1.以下代碼輸出什么悉尾?

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('男');

輸出:

name: hunger
age: 28
sex: 男
["hunger", 28, "男"]
name valley

name: hunger
age: 28
sex: undefined
["hunger", 28]
name valley

name: 男
age: undefined
sex: undefined
[男]
name valley

2.寫一個(gè)函數(shù),返回參數(shù)的平方和挫酿?

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

3.如下代碼的輸出焕襟?為什么>

console.log(a); //undefined  因?yàn)樽兞柯暶鳌皏ar a”被前置
var a = 1; 
console.log(b); //報(bào)錯(cuò)  因?yàn)椤癰”未被聲明

4.如下代碼的輸出?為什么饭豹?

sayName('world'); //hello world 因?yàn)楹瘮?shù)聲明會被前置,所以調(diào)用語句寫在函數(shù)聲明之前也是可以正常調(diào)用的
sayAge(10); //報(bào)錯(cuò) 因?yàn)楹瘮?shù)表達(dá)式不會被前置务漩,此處未解析到函數(shù)
function sayName(name){ 
    console.log('hello ', name); 
} 
var sayAge = function(age){ 
    console.log(age); 
};

5.如下代碼的輸出拄衰?為什么?

function fn(){} 
var fn = 3; 
console.log(fn); //輸出3

//等同于:

var fn;
function fn(){} 
fn = 3;
console.log(fn);

6.如下代碼的輸出?為什么?

function fn(fn2){ 
    console.log(fn2); 
    var fn2 = 3; 
    console.log(fn2); 
    console.log(fn); 
    function fn2(){ 
        console.log('fnnn2'); 
    } 
} 
fn(10);

//等同于:

function fn(fn2){
    var fn2; //變量提升
    function fn2(){ 
        console.log('fnnn2'); 
    } //函數(shù)聲明前置
    console.log(fn2); //打印函數(shù)fn2
    fn2 = 3;
    console.log(fn2); //3
    console.log(fn); //打印整個(gè)fn函數(shù)。在內(nèi)部作用域內(nèi)沒找到fn啤挎,所以往父級找欣尼,找到fn這個(gè)函數(shù)
}
fn(10);



//結(jié)果:
function fn2(){ 
        console.log('fnnn2'); 
    }
3
fn(fn2){ 
    console.log(fn2); 
    var fn2 = 3; 
    console.log(fn2); 
    console.log(fn); 
    function fn2(){ 
        console.log('fnnn2'); 
    } 
}

7.如下代碼的輸出?為什么少漆?

var fn = 1; 
function fn(fn){ 
    console.log(fn); 
} 
console.log(fn(fn));

//等同于:
var fn; //變量聲明前置
function fn(fn){ 
    console.log(fn); 
};
fn = 1; //給fn值為1
console.log(fn(fn)); //報(bào)錯(cuò) 因?yàn)榇藭r(shí)fn已經(jīng)不是一個(gè)函數(shù)

8.如下代碼的輸出?為什么?

console.log(j); //undefined 變量聲明被前置制市,還未被賦值
console.log(i); //undefined 變量聲明被前置,還未被賦值
for(var i=0; i<10; i++){ 
    var j = 100; 
} 
console.log(i); //10 循環(huán)結(jié)束時(shí)i的值為10
console.log(j); //100 j被賦值為100

//注:只有函數(shù)才具有作用域弊予,上面代碼的for循環(huán)里的變量屬于全局變量會被提升到頂部祥楣。

9.如下代碼的輸出?為什么汉柒?

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; 
    } 
}

//實(shí)際順序?yàn)椋?
var i; //變量提升
var fn; //變量提升
function fn(){ //函數(shù)聲明提升
    var i; //作用域內(nèi)變量提升
    function fn2(){ //作用域內(nèi)函數(shù)聲明提升
        i = 100; 
    } 
    console.log(i); //undefined  i還沒被賦值
    i = 99; 
    fn2(); 
    console.log(i); //100 i被賦值為100
}
i = 10; //i賦值為10
fn = 20;
console.log(i); //10

如下代碼的輸出误褪?為什么?

var say = 0; 
(function say(n){ 
    console.log(n);
    if(n<3) return; 
    say(n-1); 
}( 10 )); //n初始為10碾褂,立即執(zhí)行函數(shù)輸出10,9,8,7,6,5,4,3,2兽间,小于3停止循環(huán)
console.log(say); //0 因?yàn)榱⒓磮?zhí)行函數(shù)創(chuàng)造了私有作用域,外部不能訪問內(nèi)部變量正塌,所以此處say為0

本教程版權(quán)歸作者和饑人谷所有嘀略,轉(zhuǎn)載須說明來源!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末传货,一起剝皮案震驚了整個(gè)濱河市屎鳍,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌问裕,老刑警劉巖逮壁,帶你破解...
    沈念sama閱讀 216,744評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異粮宛,居然都是意外死亡窥淆,警方通過查閱死者的電腦和手機(jī)卖宠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來忧饭,“玉大人扛伍,你說我怎么就攤上這事〈士悖” “怎么了刺洒?”我有些...
    開封第一講書人閱讀 163,105評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長吼砂。 經(jīng)常有香客問我逆航,道長渔肩,這世上最難降的妖魔是什么因俐? 我笑而不...
    開封第一講書人閱讀 58,242評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮周偎,結(jié)果婚禮上抹剩,老公的妹妹穿的比我還像新娘。我一直安慰自己蓉坎,他們只是感情好澳眷,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,269評論 6 389
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蛉艾,像睡著了一般境蔼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上伺通,一...
    開封第一講書人閱讀 51,215評論 1 299
  • 那天箍土,我揣著相機(jī)與錄音,去河邊找鬼罐监。 笑死吴藻,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的弓柱。 我是一名探鬼主播沟堡,決...
    沈念sama閱讀 40,096評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼矢空!你這毒婦竟也來了航罗?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,939評論 0 274
  • 序言:老撾萬榮一對情侶失蹤屁药,失蹤者是張志新(化名)和其女友劉穎粥血,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,354評論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡复亏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,573評論 2 333
  • 正文 我和宋清朗相戀三年趾娃,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缔御。...
    茶點(diǎn)故事閱讀 39,745評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡抬闷,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出耕突,到底是詐尸還是另有隱情笤成,我是刑警寧澤,帶...
    沈念sama閱讀 35,448評論 5 344
  • 正文 年R本政府宣布眷茁,位于F島的核電站疹启,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏蔼卡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,048評論 3 327
  • 文/蒙蒙 一挣磨、第九天 我趴在偏房一處隱蔽的房頂上張望雇逞。 院中可真熱鬧,春花似錦茁裙、人聲如沸塘砸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,683評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽掉蔬。三九已至,卻和暖如春矾瘾,著一層夾襖步出監(jiān)牢的瞬間女轿,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,838評論 1 269
  • 我被黑心中介騙來泰國打工壕翩, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蛉迹,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,776評論 2 369
  • 正文 我出身青樓放妈,卻偏偏與公主長得像北救,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子芜抒,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,652評論 2 354

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

  • 1. 函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別 (*) 函數(shù)在JS中有三種方式來定義:函數(shù)聲明(function decla...
    進(jìn)擊的阿群閱讀 442評論 0 1
  • 函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別 (*)解析器會率先讀取函數(shù)聲明珍策,并使其在執(zhí)行任何代碼之前可以訪問;函數(shù)表達(dá)式則必須...
    coolheadedY閱讀 388評論 0 1
  • 問答部分 一宅倒、函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別攘宙? 二者表示函數(shù)的方式不一樣,如下 函數(shù)聲明(函數(shù)名稱不可少) 函數(shù)表...
    dengpan閱讀 418評論 0 0
  • 問答: 1. 函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別 (*) 在日常的任務(wù)中,JavaScript主要使用下面兩種方式創(chuàng)建...
    小木子2016閱讀 316評論 0 0
  • 概念 1模聋、函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別肩民? ECMAScript規(guī)定了三種聲明函數(shù)方式: 構(gòu)造函數(shù)首先函數(shù)也是對象...
    周花花啊閱讀 467評論 1 1