? ? ? ? ? ? ?在js中,我們最重要的是要學(xué)會函數(shù)的思想來解決問題。首先溜在,我們要明白的是函數(shù)在數(shù)學(xué)的應(yīng)用。
? ? ? ? ? ?在數(shù)學(xué)中他托,函數(shù)是來解決一些未知數(shù)掖肋。我們在解決代數(shù)問題上一些求解的方程式上,我們需要函數(shù)來進(jìn)行設(shè)一些未知數(shù)赏参,通過這些未知數(shù)和已知數(shù)的關(guān)系來進(jìn)行等式邏輯的運(yùn)算志笼,求出未知數(shù)是函數(shù)的正確的解法沿盅。這個是函數(shù)的本質(zhì)是工具,可以幫助我們解決我們的問題纫溃。在代數(shù)中腰涧,我們要知道是未知數(shù)和已知數(shù)的相互之間的關(guān)系,來構(gòu)建函數(shù)的等式紊浩。才能通過邏輯運(yùn)算(加減乘除)來進(jìn)行運(yùn)算窖铡。首先是要進(jìn)行設(shè)出未知數(shù):x ?(在編程中,我們要通過聲明變量來進(jìn)行我們要操作的邏輯運(yùn)算坊谁。需要我們設(shè)一些未知數(shù)來進(jìn)行參與邏輯運(yùn)算的時候费彼,我們可以通過var和let等關(guān)鍵字來進(jìn)行設(shè)變量(在 代數(shù)中,是我們設(shè)的未知數(shù))這樣口芍,我們就在邏輯的運(yùn)算中箍铲,去設(shè)我們需要的變量來進(jìn)行邏輯運(yùn)算的完整性。這個是編程優(yōu)雅于數(shù)學(xué)的代數(shù)的地方鬓椭。在編程的變量颠猴,是保存值的容器,也是相當(dāng)于代數(shù)中的未知數(shù) x = 5;分作用域的概念膘融,是函數(shù)中的執(zhí)行環(huán)境芙粱。局部的作用域和全局的作用域的概念。也可以通過作用域鏈來進(jìn)行一級一級的去尋找我們的要知道的變量的氧映。一直找到window對象春畔。所以,我們要應(yīng)用我們需要的變量的話岛都,我們要大膽的去通過var/let關(guān)鍵字進(jìn)行聲明變量律姨,來進(jìn)行復(fù)雜的邏輯運(yùn)算。
? ? ? ? 再談?wù)劸室撸覀兙幊痰暮瘮?shù)择份。js底層是基于對象和函數(shù)的一種編程語言,我們也是用構(gòu)造函數(shù)來進(jìn)創(chuàng)建對象烫堤,所以我們還要基于函數(shù)進(jìn)行設(shè)計(jì)編程語言的邏輯運(yùn)算荣赶。函數(shù)的創(chuàng)建是基于我們的關(guān)鍵字function來進(jìn)行創(chuàng)建定義函數(shù)。在編程的語言設(shè)計(jì)中鸽斟,主要是簡化我們的設(shè)計(jì)拔创,避免做重復(fù)的事情,函數(shù)是編寫語言中是可以重復(fù)使用的一段代碼(專業(yè)的來講:是一段腳本)富蓄,也是來源于我們的封裝的概念剩燥。封裝好一段代碼的時候,我們可以在用到的時候立倍,進(jìn)行調(diào)用灭红,這樣侣滩,函數(shù)的第一優(yōu)點(diǎn):封裝。就體現(xiàn)出來了变擒。我們要經(jīng)常封裝好我們的函數(shù)君珠,來增加我們的工具庫。
函數(shù)的真正的威力是:我們可以把不同的數(shù)據(jù)傳遞給它們娇斑,讓不同的數(shù)據(jù)來進(jìn)行不同的預(yù)訂操作葛躏。因?yàn)椋瘮?shù)的本質(zhì)就是一段代碼悠菜,就是一組操作舰攒,就是一段腳本。要注意的是:預(yù)訂悔醋。
給函數(shù)傳遞不同的操作是摩窃,我們稱為傳參。這樣芬骄,函數(shù)就不會稱為無米之炊了猾愿,就可以通過參數(shù)來進(jìn)行預(yù)訂的操作。形參是相當(dāng)于我們需要的變量账阻。在將來調(diào)用函數(shù)的時候蒂秘,可以把形參(變量)的值傳進(jìn)去函數(shù)的參數(shù)的。這樣就可以來進(jìn)行函數(shù)代碼的操作執(zhí)行淘太。所以姻僧,我們要把函數(shù)的參數(shù)看做是普通變量進(jìn)行操作。來進(jìn)行參與函數(shù)的邏輯運(yùn)算蒲牧。我們從理解到變量的角度進(jìn)行理解形參撇贺,而函數(shù)的傳參數(shù)是可以傳任意參數(shù)的。我們可以通過arguments來進(jìn)行訪問函數(shù)的形參數(shù)冰抢∷伤唬看如下代碼:
? ? ? function myFunction (a,b) {
? ? ? ? ? ? ?// 函數(shù)執(zhí)行的代碼
? ? ? ? ? ? var c = [];
? ? ? ? ? ? ?for ( ; a < b; a++) {
? ? ? ? ? ? ? ? ? ? ?c.push(a);
? ? ? ? ? ? ? ? ? ? console.log(c);
? ? ? ? ? ? ? }
? ? ? ? ? }
? ? ? ? ? myFunction(0,10);
? ? ? ? 可以看的出來,我們在給形參賦值的時候挎扰,我們是在調(diào)用函數(shù)的時候來進(jìn)行的賦予具體的值翠订,而在參數(shù)的位置是我們要對應(yīng)形參的位置,要對應(yīng)起來遵倦。這是尽超,我們要理解函數(shù)的優(yōu)點(diǎn)的地方。
? ? ? ? ?函數(shù)還有一個強(qiáng)大的地方是:函數(shù)不僅能夠(以參數(shù)的形式)接受數(shù)據(jù)骇吭,還能返回?cái)?shù)據(jù)橙弱。通過return 語句歧寺。這是函數(shù)的最大的優(yōu)點(diǎn)燥狰。不僅能接受各種數(shù)據(jù)棘脐,還可以通過return 語句返回?cái)?shù)據(jù)。也就是說龙致,給函數(shù)返回值蛀缝,(此時的函數(shù)有值),這樣目代,函數(shù)不僅是一段代碼屈梁,也可以是容器了。存放任何值了榛了。這樣在讶,我們的函數(shù)可以多元化的幫助我們解決問題了。
? ? ? ? ?在面向?qū)ο笾兴螅瘮?shù)是本質(zhì)是對象构哺,是Function類型的實(shí)例。也具有相關(guān)的屬性和方法战坤。由于函數(shù)是對象曙强,函數(shù)名是僅僅是指向?qū)ο蟮闹羔槨2粫c某個函數(shù)綁定途茫。函數(shù)通常使用函數(shù)聲明語法來定義的碟嘴。所以,我們可以把函數(shù)名當(dāng)做指向函數(shù)對象的指針囊卜。也可以通過變量形式來進(jìn)行改變函數(shù)名的指針娜扇。
? ? ?由于函數(shù)名本身也是變量。如果發(fā)生了同名的時候栅组,會產(chǎn)生覆蓋的袱衷。 ?函數(shù)沒有重載的概念的。也就是說笑窜,聲明了兩個同名的函數(shù)致燥,而結(jié)果則是后面的函數(shù)覆蓋了前面的函數(shù)。這個是函數(shù)的沒有重載的概念排截。
? ? 函數(shù)聲明與函數(shù)的表達(dá)式:函數(shù)的聲明和函數(shù)的表達(dá)式嫌蚤。函數(shù)的聲明是通過關(guān)鍵字function 來進(jìn)行聲明函數(shù)對象下的一個實(shí)例的。而函數(shù)的表達(dá)式:是通過函數(shù)名的一個賦值的方式來進(jìn)行賦值給一個變量断傲。函數(shù)的聲明是有提升機(jī)制(函數(shù)名本質(zhì)上也是變量)脱吱,也就函數(shù)調(diào)用在函數(shù)聲明的前面也是可以的,因?yàn)檫@個是有函數(shù)的聲明機(jī)制來進(jìn)行操作的认罩。代碼如下: ? ? ? ? ? ? ? ? ? ? ? ?alert(functionName(10,10)); ? ? ?/ ?/ ? 20
// 函數(shù)聲明箱蝠。通過return語句來進(jìn)行給函數(shù)賦值。
function functionName (num1,num2) {
? ? ? ?return? num1 + num2;
}
// 函數(shù)的表達(dá)式。沒有函數(shù)提升機(jī)制宦搬。系統(tǒng)會報(bào)錯牙瓢。
? ? ? alert(sum(10,10));
? var sum? = function (num1,num2) {
? ? ? return num1 + num2;
}
函數(shù)的值:函數(shù)名本身是個變量,所以间校,函數(shù)名可以當(dāng)做參數(shù)傳遞給另一個函數(shù)矾克,(函數(shù)可以接受任何類型的參數(shù))所以,函數(shù)的拓展和方法來源于函數(shù)名的本質(zhì)憔足,是指向函數(shù)對象下實(shí)例的指針胁附,(也是變量的),所以滓彰,函數(shù)名可以作為另一個函數(shù)的參數(shù)控妻。官方的說法是:不僅可以傳遞參數(shù)一樣把一個函數(shù)傳遞給另一個函數(shù),也可以將一個函數(shù)作為另一個函數(shù)的結(jié)果返回揭绑。代碼如下:
// 定義函數(shù)名當(dāng)做函數(shù)的參數(shù)來進(jìn)操作饼暑。要想函數(shù)名當(dāng)做函數(shù)的參數(shù)的話,我們必須要利用函數(shù)的值的特性進(jìn)行操作洗做。也就是說弓叛,函數(shù)名的值(變量的得有值);
// 要學(xué)會使用函數(shù)中的參數(shù)。
function callFunction (sameFunction,sameArgumentC,sameArgumentA,sameArgumentB) {
? ? ? ? ? ? ? return sameFunction(sameArgumentC,sameArgumentA,sameArgumentB);
}
// callFunction == sameFunction(sameArguments) 或者就是callFunction的第一參數(shù)是一個函數(shù)诚纸,而callFunction的值就是第一參數(shù)的(函數(shù)的執(zhí)行結(jié)果);
// 函數(shù)名
function addFunction (num1,num2,num3) {
? ? ? ? ? ? return num1 + num2 + num3;
}
// 只要保證函數(shù)的實(shí)參數(shù)對應(yīng)于函數(shù)的形參就可以撰筷。開發(fā)者的邏輯運(yùn)算只要對應(yīng)著函數(shù)的形參和實(shí)參就可以了。邏輯體系才算完整畦徘。
var result =? callFunction(addFunction,10,10,10);
? ? ? ? ?console.log(result); // 打印結(jié)果是20.
// 要訪問函數(shù)的指針而不執(zhí)行函數(shù)的話毕籽,必須去掉函數(shù)名后面的大括號。
function myFunction (name) {
? ? ? ? ? return 'hello' +'? '+ name;
}
var nameTag = callFunction(myFunction,'xuyinghao');
console.log(nameTag);? // 打印的結(jié)果就是 hello xuyinghao
// 從一個函數(shù)返回另一個函數(shù)井辆。
//? 定義一個對象屬性的大小排序的函數(shù)关筒。利用數(shù)組的sort()方法進(jìn)行排列。
function createfunctionName (propertyName) {
? ? ? ? ? ? ? ? ? ?return function (object1,object2) {
// 比較對象的屬性的大小杯缺。
? ? ? ? var value1 = object1[propertyName];
? ? ? ? ?var value2 = object2[propertyName];
// 進(jìn)行判斷值的大小蒸播。
if (value1>value2) {
? ? ?return -1;
}else if (value)
? ?// 創(chuàng)建對象的數(shù)組。
var data = [{name:'xuyinghao',age:19},{name:'ahouhang',age:18}];
// 調(diào)用數(shù)組下的sort()方法進(jìn)行排序萍肆。
// 如果在createfunctionName(),函數(shù)里傳參的話袍榆,返回的是function(object1,object2){}這個函數(shù)。這個函數(shù)就是兩個對象屬性的比較大小塘揣。
var nameSame = data.sort(createfunctionName('name'));
console.log(createfunctionName('name'));
? ? ? ?console.log(data[0].name);
data.sort(createfunctionName('age'));
console.log(data[0].age);
// 這是作為值的函數(shù)的用法:可以作為一個函數(shù)的返回值包雀,來進(jìn)行操作。