前端基礎(chǔ)(問答12)


keywords:函數(shù)聲明、函數(shù)表達(dá)式举塔、聲明前置绑警、argument、重載央渣、作用域鏈


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

函數(shù)聲明:

function functionName() {
    statement;
}

使用function關(guān)鍵字可以聲明一個(gè)函數(shù)。

函數(shù)表達(dá)式:

var functionName = function() {
    statement;
};

將函數(shù)賦給一個(gè)變量芽丹,變量將會(huì)指向函數(shù)北启,下次使用直接調(diào)用變量即可。

  • 什么是變量的聲明前置志衍?什么是函數(shù)的聲明前置暖庄?

變量的聲明前置:

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

/*實(shí)際上相當(dāng)于:
var a ;
console.log(a);
a=1;
變量會(huì)提升到最前面;
*/

函數(shù)的聲明前置:

fn();
//"1"

function fn() {
    console.log('1');
}
//實(shí)際上楼肪,和變量聲明一樣培廓,函數(shù)聲明會(huì)提升到最前面,但會(huì)在變量聲明的后面。
  • arguments 是什么春叫?

在函數(shù)內(nèi)部,你可以使用arguments對(duì)象獲取到該函數(shù)的所有傳入?yún)?shù)肩钠。類似于數(shù)組泣港。

function printPersonInfo(name, age, sex){
    console.log(name);
    console.log(age);
    console.log(sex);
    console.log(arguments);
}
  • 函數(shù)的重載怎樣實(shí)現(xiàn)?

重載价匠,即相同函數(shù)名的參數(shù)個(gè)數(shù)不同或順序不同当纱,被視為不同的函數(shù)。 在JS中沒有函數(shù)重載的概念踩窖,函數(shù)的名稱具有唯一性坡氯,參數(shù)不同或順序不同也被認(rèn)為是同一函數(shù)。

function sum (a,b) {
    return a+b;
}

function sum (a,b,c){
    return a+b+c;
}

//如果重載洋腮,則這兩個(gè)函數(shù)不同箫柳;

但在JS中可以利用遍歷arguments模仿重載的功能。例如求和:

function sum() {
    var val = 0;
    for (var i=0;i<arguments.length;i++) {
        val += arguments[i];
    }
}
  • 立即執(zhí)行函數(shù)表達(dá)式是什么啥供?有什么作用?

立即執(zhí)行函數(shù)表達(dá)式悯恍,簡稱IIFE,是指定義一個(gè)函數(shù)之后伙狐,立刻調(diào)用函數(shù)涮毫。常用的寫法有兩種:

(function(){ /* code */ }());
// 或者
(function(){ /* code */ })();

JavaScript引擎規(guī)定,如果function關(guān)鍵字出現(xiàn)在行首贷屎,一律解釋成語句罢防。因此,JavaScript引擎看到行首是function關(guān)鍵字之后豫尽,會(huì)認(rèn)為這一段都是函數(shù)的定義篙梢。

如果要立即執(zhí)行函數(shù)顷帖,解決方法就是不要讓function出現(xiàn)在行首美旧,讓引擎將其理解成一個(gè)表達(dá)式。

通常只對(duì)匿名函數(shù)使用IIFE贬墩,主要的作用是:
1榴嗅、不必為函數(shù)命名,污染全局變量陶舞;
2嗽测、在函數(shù)內(nèi)部形成單獨(dú)作用域,封裝外部無法讀取的私有變量肿孵;
參考:
詳解JavaScript立即執(zhí)行函數(shù)表達(dá)式
JavaScript的立即執(zhí)行函數(shù)

  • 什么是函數(shù)的作用域鏈唠粥?

JavaScript的每個(gè)函數(shù)function都有自己的作用域,使用Active Object(簡稱AO)活動(dòng)對(duì)象來保存停做,在相互嵌套的函數(shù)中形成了作用域鏈晤愧,如下圖所示:

作用域鏈

作用域鏈就是從里到外的AO鏈。

函數(shù)fn3中使用的變量蛉腌,如在fn3作用域?qū)ふ也坏焦俜荩瑒t往外層fn作用域?qū)ふ抑焕澹源祟愅疲钡饺謱?duì)象window舅巷。
例如:

var c = 5; 
function t1(){ 
  var d = 6; 
  function t2(){ 
    var e = 7; 
    var d = 3;
 //如果在這里聲明的var d = 3羔味,
 //那么函數(shù)就不在向外尋找變量d,輸出的值為15 
    console.log(c+d+e); 
  } 
  t2(); 
} 
t1();

再如:

    var    a = 1
    function fn1() {
        console.log(a)
        var a = 5
        function fn2() {
            console.log(a)
            a = 20
            d = 10
        }
        a++
         fn2()
        console.log(a)
        console.log(d)
    }
    fn1()
    console.log(a)
    console.log(d)
    //undefined
    //6
    //20
    //10
    //1
    //10

參考:
JavaScript.the core
深入理解JavaScript——作用域鏈

代碼

  • 以下代碼輸出什么?

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
//['hunger']
//name valley
  • 寫一個(gè)函數(shù)钠右,返回參數(shù)的平方和赋元?如

function sumOfSquares(){
    var val = 0;
    for (var i=0,length=arguments.length; i<length;i++) {
        val += arguments[i]*arguments[i]
    }
    return console.log(val);
}
sumOfSquares(2,3,4);   // 29
sumOfSquares(1,3);   // 10
  • 如下代碼的輸出?為什么

console.log(a);           //變量聲明前置
var a = 1;
console.log(b);         //b未定義
//undefined
//報(bào)錯(cuò)
  • 如下代碼的輸出飒房?為什么

sayName('world');                       //函數(shù)聲明前置
sayAge(10);                                  //函數(shù)表達(dá)式不能前置
function sayName(name){
    console.log('hello ', name);
}
var sayAge = function(age){
    console.log(age);
};
//hello world
//TypeError : sayAge is not a function
  • .如下代碼的輸出们陆?為什么

function fn(){}
var fn = 3;       //變量聲明前置,fn先是函數(shù)情屹,后被賦予數(shù)值3坪仇;
console.log(fn);

//3
  • 如下代碼的輸出?為什么

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

//上述函數(shù)相當(dāng)于:
//function fn(fn2){
//  var fn2;
//  function fn2(){
//      console.log('fnnn2');
//  }
//  console.log(fn2);
//  fn = 3;
//  console.log(fn2);
//  console.log(fn);
//}
  • 如下代碼的輸出垃你?為什么

var fn = 1;
function fn(fn){
     console.log(fn);
}
console.log(fn(fn)); 
//TypeError: fn is not a function

//實(shí)際上椅文,相當(dāng)于:
//var fn;
//function fn(fn){
//  console.log(fn);
//}
//fn = 1;
//console.log(fn(fn));
  • 如下代碼的輸出?為什么

//作用域
console.log(j);
console.log(i);
for(var i=0; i<10; i++){    //i和j變量聲明前置惜颇,i和j是全局變量
    var j = 100;
}
console.log(i);
console.log(j);

//undefined
//undefined
//10
//100
  • 如下代碼的輸出皆刺?為什么

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

//undefined
//100
//10

// 實(shí)際上,相當(dāng)于:
// var i;              
// var fn;
// function fn(){
//  var i;
//  function fn2(){
//      i = 100;         這里i是全局變量凌摄;
//  }
//  console.log(i);
//  i = 99;
//  fn2();
//  console.log(i);
// }
// fn();
// i = 10;
// fn = 20;
// console.log(i);
  • 如下代碼的輸出羡蛾?為什么

var say = 0;
(function say(n){
    console.log(n);
    if(n<3) return;
    say(n-1);
}( 10 ));
console.log(say);

// 10
// 9
// 8
// 7
// 6
// 5
// 4
// 3
// 2
// 0

//這里用到立即執(zhí)行函數(shù)表達(dá)式(IIFE),say不斷執(zhí)行锨亏,直到遇到return跳出函數(shù)痴怨,
//之后函數(shù)say被銷毀,say成為0
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末器予,一起剝皮案震驚了整個(gè)濱河市浪藻,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌乾翔,老刑警劉巖爱葵,帶你破解...
    沈念sama閱讀 212,542評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異反浓,居然都是意外死亡萌丈,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門雷则,熙熙樓的掌柜王于貴愁眉苦臉地迎上來辆雾,“玉大人,你說我怎么就攤上這事巧婶∏洌” “怎么了涂乌?”我有些...
    開封第一講書人閱讀 158,021評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長英岭。 經(jīng)常有香客問我湾盒,道長,這世上最難降的妖魔是什么诅妹? 我笑而不...
    開封第一講書人閱讀 56,682評(píng)論 1 284
  • 正文 為了忘掉前任罚勾,我火速辦了婚禮,結(jié)果婚禮上吭狡,老公的妹妹穿的比我還像新娘尖殃。我一直安慰自己,他們只是感情好划煮,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,792評(píng)論 6 386
  • 文/花漫 我一把揭開白布送丰。 她就那樣靜靜地躺著,像睡著了一般弛秋。 火紅的嫁衣襯著肌膚如雪器躏。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,985評(píng)論 1 291
  • 那天蟹略,我揣著相機(jī)與錄音登失,去河邊找鬼。 笑死挖炬,一個(gè)胖子當(dāng)著我的面吹牛揽浙,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播意敛,決...
    沈念sama閱讀 39,107評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼馅巷,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了空闲?” 一聲冷哼從身側(cè)響起令杈,我...
    開封第一講書人閱讀 37,845評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤走敌,失蹤者是張志新(化名)和其女友劉穎碴倾,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體掉丽,經(jīng)...
    沈念sama閱讀 44,299評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡跌榔,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,612評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了捶障。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片僧须。...
    茶點(diǎn)故事閱讀 38,747評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖项炼,靈堂內(nèi)的尸體忽然破棺而出担平,到底是詐尸還是另有隱情示绊,我是刑警寧澤,帶...
    沈念sama閱讀 34,441評(píng)論 4 333
  • 正文 年R本政府宣布暂论,位于F島的核電站面褐,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏取胎。R本人自食惡果不足惜展哭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,072評(píng)論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望闻蛀。 院中可真熱鬧匪傍,春花似錦、人聲如沸觉痛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽薪棒。三九已至映挂,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間盗尸,已是汗流浹背霎肯。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評(píng)論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留脸甘,地道東北人履肃。 一個(gè)月前我還...
    沈念sama閱讀 46,545評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像扣蜻,于是被迫代替她去往敵國和親逆巍。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,658評(píng)論 2 350

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