函數(shù)和作用域

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

  • 使用function關(guān)鍵字可以聲明一個函數(shù)起宽,聲明不必放在調(diào)用前面赦颇;
  • 函數(shù)表達(dá)式相當(dāng)于把一個函數(shù)當(dāng)做一個值蓬痒,賦值給一個變量舌涨,所以聲明必須放在調(diào)用前面斩例。

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

在一個作用域下拷淘,var聲明的變量和function聲明的函數(shù)會前置

//代碼段如下撇他,因?yàn)樽兞康穆暶髑爸弥裣埃栽诖a段頂部有一條隱性的聲明 var a
console.log(a); //因?yàn)槁暶髦胁]有給a賦值誊抛,所以輸出為 undefined
var a = 1;

//代碼段如下,因?yàn)楹瘮?shù)的聲明前置整陌,所以在代碼段頂部有一條隱性的聲明 function a(){}
console.log(a); //因?yàn)槁暶髦兄皇且粋€空函數(shù)拗窃,所以輸出為 function a(){}
function a(){
    console.log("hello");
};

arguments 是什么

arguments是獲取傳遞給函數(shù)所有參數(shù)的類數(shù)組對象瞎领,可以使用方括號語法來訪問每一個元素,也可以使用length屬性來確定傳遞進(jìn)函數(shù)的參數(shù)的個數(shù)随夸。

需要注意的是九默,如果定義了函數(shù)參數(shù),但沒有傳進(jìn)相應(yīng)的參數(shù)值宾毒,則沒有傳遞值的函數(shù)參數(shù)被自動賦予undefined值驼修。


函數(shù)的"重載"怎樣實(shí)現(xiàn)

JavaScript不能像強(qiáng)類型語言那樣實(shí)現(xiàn)函數(shù)重載,在定義兩個相同函數(shù)名的函數(shù)诈铛,后一個函數(shù)會將前一個覆蓋乙各,要實(shí)現(xiàn)類似的功能,可以通過檢查傳入函數(shù)中參數(shù)的不同執(zhí)行相應(yīng)的邏輯模擬重載癌瘾。


立即執(zhí)行函數(shù)表達(dá)式是什么觅丰?有什么作用

不需要顯示的調(diào)用函數(shù),在定義函數(shù)后就立即執(zhí)行的函數(shù)就是立即執(zhí)行的函數(shù)表達(dá)式妨退,它的作用是隔離作用域妇萄,不會產(chǎn)生任何全局變量。
立即執(zhí)行函數(shù)表達(dá)式的寫法有以下幾種:

(function(){ 
   ...
})();

(function(){ 
    ...
}());

求n!咬荷,用遞歸來實(shí)現(xiàn)

function factor(n) {
    if (n === 1 || n === 0) {
        return 1;
    };
    if (n < 0) {
        return "負(fù)數(shù)沒有階乘";
    };
    return n * factor(n - 1);
};
factor(n);

以下代碼輸出什么冠句?

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('饑人谷', 2, '男');
/*name: 饑人谷
age: 2
sex: 男
["饑人谷", 2, "男"]
name valley
undefined*/
getInfo('小谷', 3);
/*name: 小谷
age: 3
sex: undefined
["小谷", 3]
name valley
undefined*/
getInfo('男');
/*name: 男
age: undefined
sex: undefined
["男"]
name valley
undefined*/

寫一個函數(shù),返回參數(shù)的平方和幸乒?

function sumSquare() {
    var sum = 0;
    for (i = 0; i < arguments.length; i++) {
        sum = sum + arguments[i]*arguments[i];
    };
    return sum;
};
sumSquare();

如下代碼的輸出懦底?為什么

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

/* 將代碼段聲明前置并重寫
var a;
console.log(a);
a = 1;
console.log(b);
所以輸出結(jié)果為
undefined
Uncaught ReferenceError: b is not defined */

如下代碼的輸出?為什么

sayName('world');
sayAge(10);
function sayName(name){
    console.log('hello ', name);
}
var sayAge = function(age){
    console.log(age);
};

/* function sayName(name)是函數(shù)聲明罕扎,該函數(shù)的調(diào)用可以放在函數(shù)聲明前面聚唐,
而var sayAge = function(age)是一個函數(shù)表達(dá)式,調(diào)用必須放在后面腔召,所以代碼段的輸出如下:
hello world
Uncaught TypeError: sayAge is not a function*/

如下代碼輸出什么? 寫出作用域鏈查找過程偽代碼

var x = 10
bar()
function foo() {
  console.log(x)
}
function bar(){
  var x = 30
  foo()
}


/*
globalContext = {
    AO: {
        x: 10
        foo: function
        bar: function
    }
    Scope: null
}
foo.[[scope]]: globalContext.AO
bar.[[scope]]: globalContext.AO

barContext = {
    AO: {
        x: 30
    }
    Scope: bar.[[scope]]: globalContext.AO
}

fooContext = {
    AO: {}
    Scope: foo.[[scope]]: globalContext.AO
}

根據(jù)上面的作用域鏈查找過程偽代碼杆查,可得console.log(x)的輸出為10 undefined,則foo()為10 undefined臀蛛,則bar()為10 undefined
*/

如下代碼輸出什么? 寫出作用域鏈查找過程偽代碼

var x = 10;
bar()
function bar(){
  var x = 30;
  function foo(){
    console.log(x)
  }
  foo();
}

/*
globalContext = {
    AO: {
        x: 10
        bar: function
    }
    Scope: null
}
bar.[[scope]]: globalContext.AO

barContext = {
    AO: {
        x: 30
        foo: function
    }
    Scope: bar.[[scope]]: globalContext.AO
}
foo.[[scope]]: barContext.AO

fooContext = {
    AO: {}
    Scope: foo.[[scope]]: barContext.AO
}
根據(jù)上面的作用域鏈查找過程偽代碼亲桦,可得console.log(x)的輸出為30 undefined,則foo()為30 undefined浊仆,則bar()為30 undefined
*/

以下代碼輸出什么? 寫出作用域鏈的查找過程偽代碼

var x = 10;
bar()
function bar(){
  var x = 30;
  (function (){
    console.log(x)
  })()
}

/*
globalContext = {
    AO: {
        x: 10
        bar: function
    }
    Scope: null
}
bar.[[scope]]: globalContext.AO

barContext = {
    AO: {
        x: 30
        (function (){console.log(x)}): function
    }
    Scope: bar.[[scope]]: globalContext.AO
}
(function (){console.log(x)}).[[scope]]: bar.[[scope]]: globalContext.AO

(function (){console.log(x)}) = {
    AO: {}
    Scope: bar.[[scope]]: globalContext.AO
}
根據(jù)上面的作用域鏈查找過程偽代碼客峭,(function (){console.log(x)})()是一個立即執(zhí)行函數(shù)表達(dá)式,它的取值應(yīng)該在barContext中找抡柿,則x為30舔琅,console.log(x)的輸出為30 undefined,bar()為30 undefined
*/

以下代碼輸出什么沙绝? 寫出作用域鏈查找過程偽代碼

var a = 1;

function fn(){
  console.log(a)  //undefiend
  var a = 5
  console.log(a)  //5
  a++
  var a
  fn3()  //1
  fn2()  //6
  console.log(a)  //20

  function fn2(){
    console.log(a)
    a = 20
  }
}

function fn3(){
  console.log(a)
  a = 200
}

fn()
console.log(a)  //200

/*
globalContext = {
    AO: {
        a: 1
        fn: function
        fn3: function
    }
    Scope: null
}
fn.[[scope]]: globalContext.AO
fn3.[[scope]]: globalContext.AO

執(zhí)行fn()函數(shù)時搏明,根據(jù)聲明前置鼠锈,在第一個console.log(a)執(zhí)行時,作用域鏈查找過程偽代碼如下:
fnContext = {
    AO: {
        a: undefined
        fn2: function
    }
    Scope: fn.[[scope]]: globalContext.AO
}
fn2.[[scope]]: fnContext.AO

當(dāng)a=5時星著,作用域鏈查找過程偽代碼如下
fnContext = {
    AO: {
        a: 5
        fn2: function
    }
    Scope: fn.[[scope]]: globalContext.AO
}
fn2.[[scope]]: fnContext.AO

當(dāng)執(zhí)行a++時购笆,作用域鏈查找過程偽代碼如下
fnContext = {
    AO: {
        a: 6
        fn2: function
    }
    Scope: fn.[[scope]]: globalContext.AO
}
fn2.[[scope]]: fnContext.AO

執(zhí)行函數(shù)fn3()時,先代入fn3.[[scope]]: globalContext.AO中a的值虚循,輸出console.log(a)同欠,再重新對a賦值
fn3Context = {
    AO: {
        a: 200
    }
    Scope: fn3.[[scope]]: globalContext.AO
}
執(zhí)行fn3()后,全局上下文中a的值變?yōu)?00

執(zhí)行函數(shù)fn2()時横缔,先代入fn2.[[scope]]: fnContext.AO中a的值铺遂,輸出console.log(a),再重新對a賦值
fn2Context = {
    AO: {
        a: 20
    }
    Scope: fn2.[[scope]]: fnContext.AO
}
執(zhí)行fn2()后茎刚,fn()中a的值變?yōu)?0

根據(jù)上面的計算襟锐,最終的詳細(xì)輸出結(jié)果為:
fn()共輸出5個值,一一對應(yīng)為
    第一個console.log(a) => undefined
    第二個console.log(a) => 5
    fn3() => 1
    fn2() => 6
    第三個console.log(a) => 20
代碼段最后一個console.log(a) => 200 undefined
*/
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末膛锭,一起剝皮案震驚了整個濱河市粮坞,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌初狰,老刑警劉巖莫杈,帶你破解...
    沈念sama閱讀 221,888評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異奢入,居然都是意外死亡筝闹,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評論 3 399
  • 文/潘曉璐 我一進(jìn)店門腥光,熙熙樓的掌柜王于貴愁眉苦臉地迎上來关顷,“玉大人,你說我怎么就攤上這事武福〗馇蓿” “怎么了?”我有些...
    開封第一講書人閱讀 168,386評論 0 360
  • 文/不壞的土叔 我叫張陵艘儒,是天一觀的道長。 經(jīng)常有香客問我夫偶,道長界睁,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,726評論 1 297
  • 正文 為了忘掉前任兵拢,我火速辦了婚禮翻斟,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘说铃。我一直安慰自己访惜,他們只是感情好嘹履,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,729評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著债热,像睡著了一般砾嫉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上窒篱,一...
    開封第一講書人閱讀 52,337評論 1 310
  • 那天焕刮,我揣著相機(jī)與錄音,去河邊找鬼墙杯。 笑死配并,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的高镐。 我是一名探鬼主播溉旋,決...
    沈念sama閱讀 40,902評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼嫉髓!你這毒婦竟也來了观腊?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,807評論 0 276
  • 序言:老撾萬榮一對情侶失蹤岩喷,失蹤者是張志新(化名)和其女友劉穎恕沫,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體纱意,經(jīng)...
    沈念sama閱讀 46,349評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡婶溯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,439評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了偷霉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片迄委。...
    茶點(diǎn)故事閱讀 40,567評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖类少,靈堂內(nèi)的尸體忽然破棺而出叙身,到底是詐尸還是另有隱情,我是刑警寧澤硫狞,帶...
    沈念sama閱讀 36,242評論 5 350
  • 正文 年R本政府宣布信轿,位于F島的核電站,受9級特大地震影響残吩,放射性物質(zhì)發(fā)生泄漏财忽。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,933評論 3 334
  • 文/蒙蒙 一泣侮、第九天 我趴在偏房一處隱蔽的房頂上張望即彪。 院中可真熱鬧,春花似錦活尊、人聲如沸隶校。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽深胳。三九已至绰疤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間稠屠,已是汗流浹背峦睡。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留权埠,地道東北人榨了。 一個月前我還...
    沈念sama閱讀 48,995評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像攘蔽,于是被迫代替她去往敵國和親龙屉。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,585評論 2 359

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

  • 1满俗、 函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別 ECMAScript規(guī)定了三種聲明函數(shù)方式:構(gòu)造函數(shù)转捕、函數(shù)聲明、和函數(shù)表達(dá)式...
    熊蛋子17閱讀 402評論 0 2
  • 1.函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別 (*) 函數(shù)聲明 函數(shù)表達(dá)式 函數(shù)聲明:函數(shù)調(diào)用可以發(fā)生在函數(shù)聲明之前,例如下...
    TimeLesser閱讀 398評論 4 4
  • 1.函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別 函數(shù)聲明和函數(shù)表達(dá)式是聲明函數(shù)的兩種不同的方式,形式如下: 函數(shù)聲明:即使用f...
    饑人谷_bigJiao閱讀 235評論 0 0
  • 1.函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別 函數(shù)聲明 使用 function 關(guān)鍵字聲明一個函數(shù) 聲明不必放到調(diào)用的前面唆垃,...
    Soarse閱讀 207評論 0 0
  • 1.函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別? 函數(shù)聲明必須有標(biāo)識符五芝,也就是常說的函數(shù)名;函數(shù)表達(dá)式可以省略函數(shù)名.函數(shù)聲明...
    Schrodinger的貓閱讀 246評論 0 0