javascript 函數(shù)(函數(shù)的定義和調(diào)用)

函數(shù)的定義和調(diào)用

arguments

arguments盲再,它只在函數(shù)內(nèi)部起作用周崭,并且永遠(yuǎn)指向當(dāng)前函數(shù)的調(diào)用者傳入的所有參數(shù)哑诊,可以獲得調(diào)用者傳入的所有參數(shù)撒璧。arguments類似Array但它不是一個Array:

function foo(x) {
  console.log(x);  // 10
  for (var i = 0;  i < arguments.length;  i++) {
    console.log(arguments[i]);  // 10, 20, 30
  }
}
foo(10, 20, 30);

那在什么情況下才會真正用到arguments呢透葛,下面舉個栗子:

函數(shù)的重載:

有時候函數(shù)根據(jù)傳入的參數(shù)個數(shù)的不同,來執(zhí)行不同的處理:

// 如果用戶傳入一個參數(shù)卿樱,求平方
function sum(a){
    console.log(a*a);
}

//如果用戶傳入兩個參數(shù)僚害,就求和
function sum(a,b){
    console.log(a+b);
}
sum(4); //?
sum(4,5); //繁调?

上述例子中本意是想讓同名函數(shù)sum()根據(jù)參數(shù)不同輸出不同結(jié)果萨蚕,但是sum是函數(shù)名字,本質(zhì)也是個變量蹄胰,
第二個會覆蓋第一個岳遥,所以上述的正確輸出答案是:NaN,9.所以這樣顯然不可以。
如果用arguments,就簡單多了裕寨。

如下:

function calc(){
    //如果用戶傳入一個參數(shù)浩蓉,求平方
    if(arguments.length===1){
        console.log(arguments[0]*arguments[0]);
    }else if(arguments.length===2){
    //如果用戶傳入兩個參數(shù),就求和
        console.log(arguments[0]+arguments[1]);
    }
}
calc(4); //16
calc(4, 5); //9

多個參數(shù)的求和:

function add(){
    //arguments:[]
    //遍歷arguments中每個元素宾袜,并累加
    for(var i=0,sum=0;i<arguments.length;sum+=arguments[i++]);
    return sum;//返回和
}

console.log(add(1, 2, 3)); //6
console.log(add(1, 2, 3, 4, 5, 6)); //21

這就是JS利用arguments重載的效果捻艳,簡單理解就是一個函數(shù)重復(fù)利用.
arguments.length是有實參決定,即函數(shù)調(diào)用時候里面的參數(shù)個數(shù)決定试和!

arguments對象中還定義了callee屬性讯泣,用來引用當(dāng)前正在執(zhí)行的函數(shù)纫普,例如在遞歸中使用:

function factorial(num) {

    // 參數(shù)的callee是函數(shù)自身
    console.log(arguments.callee === foo); // true

    if(num <=1 ) {
        return 1;
    } else {
        return num*arguments.callee(num-1);
    }
}

console.log(factorial(5));//120

需要注意的是如果一個函數(shù)的參數(shù)有3個,傳遞的實參只有2個,那么arguments[2]和第三個參數(shù)是不共享的.

function foo(x, y, z) {

    // 聲明的函數(shù)參數(shù)數(shù)量arguments (x, y, z)
    console.log(foo.length); // 3

    // 真正傳進(jìn)來的參數(shù)個數(shù)(only x, y)
    console.log(arguments.length); // 2

    // 參數(shù)共享

    console.log(x === arguments[0]); // true
    console.log(x); // 10

    arguments[0] = 20;
    console.log(x); // 20

    x = 30;
    console.log(arguments[0]); // 30

    // 不過阅悍,沒有傳進(jìn)來的參數(shù)z好渠,和參數(shù)的第3個索引值是不共享的

    z = 40;
    console.log(arguments[2]); // undefined

    arguments[2] = 50;
    console.log(z); // 40
}

foo(10, 20);
rest參數(shù)

ES6標(biāo)準(zhǔn)引入了rest參數(shù):

function foo(a, b, ...rest) {
    console.log('a = ' + a);
    console.log('b = ' + b);
    console.log(rest);
}

foo(1, 2, 3, 4, 5);
// 結(jié)果:
// a = 1
// b = 2
// Array [ 3, 4, 5 ]

foo(1);
// 結(jié)果:
// a = 1
// b = undefined
// Array []

rest參數(shù)只能寫在最后,前面用 ... 標(biāo)識节视,從運行結(jié)果可知拳锚,傳入的參數(shù)先綁定a、b寻行,多余的參數(shù)以數(shù)組形式交給變量rest霍掺,所以,不再需要arguments我們就獲取了全部參數(shù)拌蜘。

如果傳入的參數(shù)連正常定義的參數(shù)都沒填滿杆烁,也不要緊,rest參數(shù)會接收一個空數(shù)組(注意不是undefined)简卧。

變量的作用域

我們知道在JavaScript中兔魂, 在函數(shù)內(nèi)var一個變量,則該變量的作用域為整個函數(shù)體举娩,在函數(shù)體外不可引用該變量析校;

不同的函數(shù)體聲明同一個變量,相互不會影響铜涉,各自的作用域只在各自所在函數(shù)體內(nèi)智玻。也就是說不同函數(shù)內(nèi)部的同名變量互相獨立,互不影響芙代;

上面描述了平行關(guān)系的函數(shù)內(nèi)部變量及作用域的特點吊奢,JavaScript可以存在嵌套函數(shù),此時的內(nèi)部函數(shù)可以訪問外部函數(shù)定義的變量链蕊,外部則不可訪問外部;

'use strict';

function foo() {
    var x = 1;
    function bar() {
        var y = x + 1; 
    }
    var z = y + 1; // foo() 時這里會因為無法訪問y而報錯
}

如果內(nèi)部函數(shù)和外部函數(shù)的變量名重名事甜,則內(nèi)部函數(shù)的變量將“屏蔽”外部函數(shù)的變量。由此說明JavaScript的函數(shù)在查找變量時從自身函數(shù)定義開始滔韵。

'use strict';

function foo() {
    var i = 'a';
    function fuc() {
        var i =  'b';
        console.log('fuc', i); 
    }
    console.log('foo', i); 
    fuc();
}
 foo(); 
 // 'foo', a
 //  'fuc', b     
變量提升

JavaScript的函數(shù)定義有個特點逻谦,它會先掃描整個函數(shù)體的語句,把所有申明的變量“提升”到函數(shù)頂部:

'use strict';

function foo() {
    var i = 'Hello, ' + j;
    alert(i);
    var j = 'Bob';
}

foo(); // Hello, undefined

JavaScript引擎自動提升了變量j的聲明陪蜻,但不會提升變量j的賦值;
因此邦马,我們在函數(shù)內(nèi)部定義變量時,請嚴(yán)格遵守“在函數(shù)內(nèi)部優(yōu)先申明所有變量”這一規(guī)則宴卖。

全局作用域

不在任何函數(shù)內(nèi)定義的變量就具有全局作用域;
JavaScript實際上有一個默認(rèn)(唯一一個)全局作用域 window;
全局作用域的變量實際上被綁定到window的一個屬性:

'use strict';

var animal = 'White cat';
alert(animal); // 'White cat'
alert(window.animal); // 'White cat'
全局作用域有哪些需要注意的點

1滋将、名字空間
全局變量會綁定到window上,如果再不同的js文件里定義了相同的全局變量(包括頂層函數(shù)症昏,不在任何函數(shù)體內(nèi)的變量等)随闽,都會引起沖突,而且在項目中很難被發(fā)現(xiàn)肝谭。為減少這種沖突掘宪,我們可以把所以的變量和函數(shù)綁定在一個全局變量中蛾扇。

2、局部作用域
在for循環(huán)等語句塊中是無法定義具有局部作用域的變量的:

'use strict';

function foo() {
    for (var i=0; i<10; i++) {
    //
    }
    i += 10; // 仍然可以引用變量i
}

ES6引入了新的關(guān)鍵字let魏滚,用let替代var可以申明一個塊級作用域的變量镀首,用來解決以上所訴問題。

3鼠次、常量
在ES6之前更哄,我們通常用全部大寫的變量來表示一個常量,ES6標(biāo)準(zhǔn)引入了新的關(guān)鍵字const來定義常量腥寇,const與let都具有塊級作用域成翩。

this指針

在一個方法內(nèi)部,this是一個特殊變量赦役,它始終指向當(dāng)前對象捕传。
沒有綁定在對象上的函數(shù),它的this指針指向全局對象扩劝,也就是window庸论。
不知道設(shè)計者在設(shè)計之初是作何考慮的,ECMA想要優(yōu)化這個“特性”棒呛,在strict模式下讓函數(shù)的this指向undefined聂示。但并沒有根本解決this指向的問題。
因此有時我們需要用一個變量比如 that 來提前捕獲this簇秒。

參考資料:廖雪峰的官方網(wǎng)站:https://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末鱼喉,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子趋观,更是在濱河造成了極大的恐慌扛禽,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件皱坛,死亡現(xiàn)場離奇詭異编曼,居然都是意外死亡,警方通過查閱死者的電腦和手機剩辟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進(jìn)店門掐场,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人贩猎,你說我怎么就攤上這事熊户。” “怎么了吭服?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵嚷堡,是天一觀的道長。 經(jīng)常有香客問我艇棕,道長蝌戒,這世上最難降的妖魔是什么绿饵? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮瓶颠,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘刺桃。我一直安慰自己粹淋,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布瑟慈。 她就那樣靜靜地躺著桃移,像睡著了一般。 火紅的嫁衣襯著肌膚如雪葛碧。 梳的紋絲不亂的頭發(fā)上借杰,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天,我揣著相機與錄音进泼,去河邊找鬼蔗衡。 笑死,一個胖子當(dāng)著我的面吹牛乳绕,可吹牛的內(nèi)容都是我干的绞惦。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼洋措,長吁一口氣:“原來是場噩夢啊……” “哼济蝉!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起菠发,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤王滤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后滓鸠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體雁乡,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年糜俗,在試婚紗的時候發(fā)現(xiàn)自己被綠了蔗怠。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡吩跋,死狀恐怖寞射,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情锌钮,我是刑警寧澤桥温,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站梁丘,受9級特大地震影響侵浸,放射性物質(zhì)發(fā)生泄漏旺韭。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一掏觉、第九天 我趴在偏房一處隱蔽的房頂上張望区端。 院中可真熱鬧,春花似錦澳腹、人聲如沸织盼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽沥邻。三九已至,卻和暖如春羊娃,著一層夾襖步出監(jiān)牢的瞬間唐全,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工蕊玷, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留邮利,地道東北人。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓垃帅,卻偏偏與公主長得像近弟,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子挺智,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,779評論 2 354

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

  • 函數(shù)參數(shù)的默認(rèn)值 基本用法 在ES6之前祷愉,不能直接為函數(shù)的參數(shù)指定默認(rèn)值,只能采用變通的方法赦颇。 上面代碼檢查函數(shù)l...
    呼呼哥閱讀 3,384評論 0 1
  • 函數(shù)就是最基本的一種代碼抽象的方式二鳄。 定義函數(shù)function abs(x) {if (x >=0){return...
    _我和你一樣閱讀 445評論 0 0
  • 1 “這工資太低了订讼!“ “談不攏,我立馬就走人扇苞!” “反正還沒有簽合同欺殿!” “我有什么好怕的,正好我想去讀研究生鳖敷。...
    喻小歡閱讀 503評論 0 0
  • 我不想主動找你 即使我在想你 假裝我掌握著主動權(quán)力 找你不找你要看我的脾氣 我不想主動找你 即使我又想你 假裝你不...
    懶牽牛閱讀 538評論 2 3
  • 我一直不太喜歡使用語音聊天脖苏,這次回復(fù)朋友之后,我按開自己的語音定踱,發(fā)現(xiàn)許多自己表達(dá)上的問題棍潘。如下: ①語言邏輯混亂,...
    Bovin博文君閱讀 276評論 0 0