函數(shù)與作用域

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

function命令聲明的代碼區(qū)塊,就是一個函數(shù)纽竣。function命令后面是函數(shù)名坠韩,函數(shù)名后面是一對圓括號,里面是傳入函數(shù)的參數(shù)孕暇。函數(shù)體放在大括號里面仑撞。

function print(s) {
  console.log(s);
}```
除了用function命令聲明函數(shù),還可以采用變量賦值的寫法妖滔。

var print = function(s) {
console.log(s);
};```
這種寫法將一個匿名函數(shù)賦值給變量隧哮。這時,這個匿名函數(shù)又稱函數(shù)表達(dá)式(Function Expression)座舍,因?yàn)橘x值語句的等號右側(cè)只能放表達(dá)式近迁。
函數(shù)的表達(dá)式需要在語句的結(jié)尾加上分號,表示語句結(jié)束簸州。而函數(shù)的聲明在結(jié)尾的大括號后面不用加分號鉴竭。

區(qū)別:

函數(shù)聲明:聲明不必放到調(diào)用的前面
函數(shù)表達(dá)式:聲明必須放到調(diào)用的前面

JavaScript 解釋器中存在一種變量聲明被提升(hoisting)的機(jī)制,也就是說變量(函數(shù))的聲明會被提升到作用域的最前面岸浑,即使寫代碼的時候是寫在最后面搏存,也還是會被提升至最前面。
例如以下代碼段:

alert(foo); // function foo() {}
alert(bar); // undefined
function foo() {}
var bar = function bar_fn() {};
alert(foo); // function foo() {}
alert(bar); // function bar_fn() {}```
輸出結(jié)果分別是function foo() {}矢洲、undefined璧眠、function foo() {}和function bar_fn() {}。
可以看到 foo 的聲明是寫在 alert 之后读虏,仍然可以被正確調(diào)用责静,因?yàn)?JavaScript 解釋器會將其提升到 alert 前面,而以函數(shù)表達(dá)式創(chuàng)建的函數(shù) bar 則不享受此待遇盖桥。

# 2.什么是變量的聲明前置灾螃?什么是函數(shù)的聲明前置
在一個作用域下,var 聲明的變量和function 聲明的函數(shù)會前置
與全局作用域一樣揩徊,函數(shù)作用域內(nèi)部也會產(chǎn)生“變量提升”現(xiàn)象腰鬼。var命令聲明的變量嵌赠,不管在什么位置,變量聲明都會被提升到函數(shù)體的頭部熄赡。
# 3.arguments 是什么
由于JavaScript允許函數(shù)有不定數(shù)目的參數(shù)姜挺,所以我們需要一種機(jī)制,可以在函數(shù)體內(nèi)部讀取所有參數(shù)彼硫。這就是arguments對象的由來炊豪。

arguments對象包含了函數(shù)運(yùn)行時的所有參數(shù),arguments[0]就是第一個參數(shù)拧篮,arguments[1]就是第二個參數(shù)词渤,以此類推。這個對象只有在函數(shù)體內(nèi)部他托,才可以使用掖肋。
# 4.函數(shù)的"重載"怎樣實(shí)現(xiàn)
>函數(shù)重載(英語:Function overloading),是Ada赏参、C++志笼、C#、D和Java等編程語言中具有的一項(xiàng)特性把篓,這項(xiàng)特性允許創(chuàng)建數(shù)項(xiàng)名稱相同但功能的輸入輸出類型不同的子程序纫溃,它可以簡單地稱為一個單獨(dú)功能可以執(zhí)行多項(xiàng)任務(wù)的能力。

其他語言重載范例

int sum(int num1, int num2){
return num1 + num2;
}

float sum(float num1, float num2){
return num1 + num2;
}

sum(1, 2);
sum(1.5, 2.4);

Javascript中韧掩,先定義的函數(shù)紊浩,會被后定義的函數(shù)覆蓋。因此Javascript不支持函數(shù)的重載疗锐,不能夠定義同樣的函數(shù)然后通過編譯器去根據(jù)不同的參數(shù)執(zhí)行不同的函數(shù)坊谁。

但是javascript卻可以通過自身屬性去模擬函數(shù)重載。
變相實(shí)現(xiàn)函數(shù)重載的方法:
- 利用arguments對象

<script type="text/javascript">
function showSum()
{
//使用arguments對象模擬出重載效果
if (arguments.length == 1)
{
alert(arguments[0] + 1);
}
else if (arguments.length == 2)
{
alert(arguments[0] + arguments[1]);
}
else if (arguments.length == 3)
{
alert(arguments[0] + arguments[1] + arguments[2]);
}
else {
alert('請傳入?yún)?shù)滑臊!');
}
}
//顯示101
showSum(100);
//顯示200
showSum(100, 100);
//顯示300
showSum(100, 100,100);
</script>```

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

立即執(zhí)行函數(shù)就是
1.聲明一個匿名函數(shù)
2.馬上調(diào)用這個匿名函數(shù)

JavaScript引擎規(guī)定鬓椭,如果function關(guān)鍵字出現(xiàn)在行首,一律解釋成語句关划,為了兼容 JS 的語法小染。避免瀏覽器報(bào)語法錯誤,可以這樣寫:
(function(){alert('我是匿名函數(shù)')} ()) // 用括號把整個表達(dá)式包起來
(function(){alert('我是匿名函數(shù)')}) () //用括號把函數(shù)包起來
!function(){alert('我是匿名函數(shù)')}() // 求反贮折,我們不在意值是多少裤翩,只想通過語法檢查。
+function(){alert('我是匿名函數(shù)')}()
-function(){alert('我是匿名函數(shù)')}()
~function(){alert('我是匿名函數(shù)')}()
void function(){alert('我是匿名函數(shù)')}()
new function(){alert('我是匿名函數(shù)')}()

只有一個作用:創(chuàng)建一個獨(dú)立的作用域脱货。
這個作用域里面的變量岛都,外面訪問不到(即避免「變量污染」)律姨。
參考文章:https://zhuanlan.zhihu.com/p/22465092

6.求n!振峻,用遞歸來實(shí)現(xiàn)

function factor(n){
  if(n === 1) {
    return 1;
  }
  return n * factor(n-1);
}

factor(5);

注意:求遞歸的時候要考慮負(fù)數(shù)和0臼疫;

7.以下代碼輸出什么?

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, '男');
getInfo('小谷', 3);
getInfo('男');
 name: 饑人谷
 age: 2
 sex: 男
 ["饑人谷", 2, "男", callee: function, Symbol(Symbol.iterator): function]
 name valley

 name: 小谷
 age: 3
 sex: undefined
 ["小谷", 3, callee: function, Symbol(Symbol.iterator): function]
 name valley

 name: 男
 age: undefined
 sex: undefined
 ["男", callee: function, Symbol(Symbol.iterator): function]
 name valley

8 寫一個函數(shù)扣孟,返回參數(shù)的平方和烫堤?

 function sumOfSquares(){
var sum = 0;
   for (var i = 0; i<arguments.length; i++) {
       sum = sum+arguments[i]*arguments[i];
}
    return sum;
   }
   var result = sumOfSquares(2,3,4)
   var result2 = sumOfSquares(1,3)
   console.log(result) 
   console.log(result2)

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

    console.log(a);//undefined;變量a被提升
    var a = 1;
    console.log(b);//Uncaught ReferenceError: b is not defined;b未聲明

10. 如下代碼的輸出凤价?為什么

sayName('world');
sayAge(10);
function sayName(name){
    console.log('hello ', name);//hello world;函數(shù)聲明被提升到代碼最前面鸽斟。
}
var sayAge = function(age){
    console.log(age);//Uncaught TypeError: sayAge is not a function;這是函數(shù)表達(dá)式,只有var sayAge被提升到代碼前面利诺;
};

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

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

函數(shù)本身也是一個值富蓄,也有自己的作用域。它的作用域與變量一樣慢逾,就是其聲明時所在的作用域立倍,與其運(yùn)行時所在的作用域無關(guān)÷绿玻總之口注,函數(shù)執(zhí)行時所在的作用域,是定義時的作用域君珠,而不是調(diào)用時所在的作用域寝志。

globalContext = {
  AO: {
    x: 10
    foo: function
    bar: function
  },
  Scope: null
}

barContext= {
AO: {
     x:30
   }
scope:globalContext.AO
}

fooContex= {
AO: {}
scope:globalContext.AO
}

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

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

globalContext = {
AO: {
x: 10
bar: function
},
Scope: null
}

barContext= {
AO: {
x:30
foo: function
}
scope:globalContext.AO
}

fooContex= {
AO: {}
scope:barContext.AO
}

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

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

globalContext = {
  AO: {
    x: 10
    bar: function
  },
  Scope: null
}

barContext= {
AO: {
     x:30
   }
scope:globalContext.AO
}

fooContex= {
AO: {}
scope:barContext.AO
}

立即執(zhí)行函數(shù)的作用域鏈 與普通函數(shù)作用域鏈一樣.(要說區(qū)別,立即不會提升)

14. 以下代碼輸出什么策添? 寫出作用域鏈查找過程偽代碼

var a = 1;

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

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

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

fn()
console.log(a)//200
globalContext = {
  AO: {
    a: 1
    fn: function
    fn3: function
  },
  Scope: null
}

fnContext= {
AO: {
     a:5
     fn2: function
   }
scope:globalContext.AO
}

fn2Contex= {
AO: {}
scope:fnContext.AO
}

fn3Contex= {
AO: {}
scope:globalContext.AO
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末材部,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子唯竹,更是在濱河造成了極大的恐慌乐导,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,376評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件摩窃,死亡現(xiàn)場離奇詭異兽叮,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)猾愿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評論 2 385
  • 文/潘曉璐 我一進(jìn)店門鹦聪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蒂秘,你說我怎么就攤上這事泽本。” “怎么了姻僧?”我有些...
    開封第一講書人閱讀 156,966評論 0 347
  • 文/不壞的土叔 我叫張陵规丽,是天一觀的道長蒲牧。 經(jīng)常有香客問我,道長赌莺,這世上最難降的妖魔是什么冰抢? 我笑而不...
    開封第一講書人閱讀 56,432評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮艘狭,結(jié)果婚禮上挎扰,老公的妹妹穿的比我還像新娘。我一直安慰自己巢音,他們只是感情好遵倦,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,519評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著官撼,像睡著了一般梧躺。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上傲绣,一...
    開封第一講書人閱讀 49,792評論 1 290
  • 那天掠哥,我揣著相機(jī)與錄音,去河邊找鬼斜筐。 笑死龙致,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的顷链。 我是一名探鬼主播目代,決...
    沈念sama閱讀 38,933評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼嗤练!你這毒婦竟也來了榛了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,701評論 0 266
  • 序言:老撾萬榮一對情侶失蹤煞抬,失蹤者是張志新(化名)和其女友劉穎霜大,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體革答,經(jīng)...
    沈念sama閱讀 44,143評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡战坤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,488評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了残拐。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片途茫。...
    茶點(diǎn)故事閱讀 38,626評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖溪食,靈堂內(nèi)的尸體忽然破棺而出囊卜,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 34,292評論 4 329
  • 正文 年R本政府宣布栅组,位于F島的核電站雀瓢,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏玉掸。R本人自食惡果不足惜刃麸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,896評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望排截。 院中可真熱鬧嫌蚤,春花似錦辐益、人聲如沸断傲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽认罩。三九已至,卻和暖如春续捂,著一層夾襖步出監(jiān)牢的瞬間垦垂,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工牙瓢, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留劫拗,地道東北人。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓矾克,卻偏偏與公主長得像页慷,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子胁附,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,494評論 2 348

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

  • 函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別 JavaScript 中需要創(chuàng)建函數(shù)的話酒繁,有兩種方法:函數(shù)聲明、函數(shù)表達(dá)式控妻,各自寫...
    蕭雪圣閱讀 949評論 2 2
  • 函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別 函數(shù)聲明:function fn(){}; 函數(shù)表達(dá)式: var fn = fun...
    cross_王閱讀 255評論 0 0
  • 1.函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別 函數(shù)聲明:function functionName(){};使用functi...
    saintkl閱讀 201評論 0 0
  • 1. 函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別 使用function關(guān)鍵字聲明一個函數(shù)時州袒,聲明不必放到調(diào)用的前面。//函數(shù)聲...
    _李祺閱讀 271評論 0 0
  • 原來音樂中也有核心素養(yǎng)弓候,要想唱好歌必須要有音色的支撐郎哭!我在思考問題音樂課對學(xué)生應(yīng)該如何去評價(jià)?它對一個人的成長影響...
    時刻記憶閱讀 176評論 0 0