日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

JavaScript快速入门(四)——JavaScript函数

發(fā)布時(shí)間:2023/12/10 javascript 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JavaScript快速入门(四)——JavaScript函数 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

函數(shù)聲明

之前說的三種函數(shù)聲明中(參見JavaScript快速入門(二)——JavaScript變量),使用Function構(gòu)造函數(shù)的聲明方法比較少見,我們暫時(shí)不提。function func() { }和var func = function() { }除了在聲明提升中有所不同之外也沒有其他不同,我們合并起來一起看。我們在這里著重講一個(gè)東西——匿名函數(shù)。

匿名函數(shù)顧名思義,就是沒有名字的函數(shù)。它的形式就是function() { }。請注意和之前說的兩種方式的區(qū)別,這里并沒有賦值給任何變量,也就是說,沒有指向這個(gè)函數(shù)的引用,我們無法在其他地方調(diào)用這個(gè)函數(shù),也就是說,這種函數(shù)的使用價(jià)值只有一次。當(dāng)我們把匿名函數(shù)賦值給其他變量時(shí),就變成了var func = function() { }。是不是很熟悉?沒錯(cuò),就是我們之前說的變量聲明的方法。而如果func是隱式聲明的話,那么,這個(gè)函數(shù)就變成了全局函數(shù)。

匿名函數(shù)使用非常廣泛,它常用于只執(zhí)行一次的函數(shù),例如排序函數(shù),我們可以這樣來寫:

?

var a = [2,1,4,7,5]; a.sort(function(num1, num2) {return num1 > num2; })

我們傳了個(gè)匿名函數(shù)作為參數(shù),因?yàn)檫@個(gè)函數(shù)只適用于這個(gè)地方,而無法用在其他地方。但如果是類似的地方也用了類似的函數(shù),例如我們需要兩次排序:

?

?

var a = [2,1,4,7,5],b = [4,2,6,4,1]; function sortDesc(num1, num2) {return num1 > num2; } a.sort(sortDesc); b.sort(sortDesc);

我們就可以把這個(gè)匿名函數(shù)剝離出來賦給一個(gè)function類型的變量,達(dá)到重復(fù)利用的目的。

?

由上面這個(gè)例子我們可以看出匿名函數(shù)的優(yōu)劣。壞處很明顯,就是無法再次利用;好處是減少了聲明的消耗(當(dāng)然,如果有兩次以上的利用的話,當(dāng)然是聲明的消耗更少)。

?

函數(shù)調(diào)用

函數(shù)的調(diào)用和C中差不多,但形式可能有點(diǎn)不同。JavaScript的函數(shù)調(diào)用形式為:(函數(shù))(參數(shù)列表)或者函數(shù)名(參數(shù)列表)。后者和C是一樣的,但前者和C是迥然不同的,因?yàn)镃中函數(shù)聲明和函數(shù)調(diào)用是區(qū)分開的。先來看下例子: function add(num1, num2) {return num1 + num2; } var a = add(1, 2); // 3 這種方式就是函數(shù)名(參數(shù)列表)的形式,我們在C中經(jīng)常見到,就不詳細(xì)說了,我們可以把上面那個(gè)換種形式來展現(xiàn): var a = (function add(num1, num2) {return num1 + num2; })(1, 2); console.log(a); // 3 這樣我們就能實(shí)現(xiàn)聲明和執(zhí)行一塊處理。 但是這樣有個(gè)問題,我們再看一種情況: var a = (function add(num1, num2) {return num1 + num2; })(1, 2); var b = add(1, 2); // error,add is not defined console.log(a); // 3 console.log(b); // undefined 這是因?yàn)閍dd這個(gè)變量的作用域僅限于括號(hào)內(nèi),這個(gè)在之后的作用域講解中將講到。 這樣的調(diào)用,一般是在匿名函數(shù)中,為了讓函數(shù)立即執(zhí)行才使用這種方式,又或者,利用它的不足,利用JavaScript的作用域特點(diǎn),將函數(shù)內(nèi)的變量全部轉(zhuǎn)為局部變量,達(dá)到封裝和防止污染全局的目的。

函數(shù)嵌套

JavaScript的函數(shù)理論上是可以無限嵌套的,當(dāng)然并不推薦嵌套太多,原因有很多,無論是性能還是代碼簡潔要求,都要求不應(yīng)該嵌套太多。我們舉一個(gè)嵌套的例子: function getAbs(num) {function isNegative(num) {return num < 0;}return isNegative(num) ? -num : num; } var a = getAbs(-1); // 1 記住一句話,有嵌套就有父子關(guān)系(相互嵌套的不在參考范圍內(nèi),也極度不推薦)。在上面的例子中,父函數(shù)即為getAbs,子函數(shù)為isNegative。 在JavaScript的嵌套中,涉及到作用域的問題,我們先不講太復(fù)雜的,簡單的可以記成:父函數(shù)中聲明的所有變量,或者說,父函數(shù)中能使用的變量,都能在子函數(shù)中使用,但反過來,子函數(shù)中顯式聲明的所有變量,都不能在父函數(shù)中使用。下面會(huì)講到caller和callee來幫助理解嵌套。

arguments對象

函數(shù)中,有一個(gè)默認(rèn)的對象,不需要你去聲明,也不需要你去賦值,它叫做arguments,它是一個(gè)數(shù)組,保存著參數(shù)列表。先來看一個(gè)例子: function add(num1, num2) {console.log(arguments); // [1, 2]return num1 + num2; }; var b = add(1, 2); 注意,arguments對象保存的是實(shí)參。接下來,我們要展示JavaScript中非常有意思的一個(gè)東西,也是JavaScript靈活性的一大體現(xiàn)。在這之前,我們先來談下C中的函數(shù)重載。 維基中的定義為:函數(shù)重載(Function overloading),是Ada、C++、C#、D和Java等編程語言中具有的一項(xiàng)特性,這項(xiàng)特性允許創(chuàng)建數(shù)項(xiàng)名稱相同但功能的輸入輸出類型不同的子程序,它可以簡單地稱為一個(gè)單獨(dú)功能可以執(zhí)行多項(xiàng)任務(wù)的能力。 在函數(shù)重載中,輸出類型可相同可不同,但參數(shù)列表一定要不一樣,可以是數(shù)量不一樣或者類型不一樣,或者兩者都不一樣。 但在JavaScript這類弱類型語言中,類型無法預(yù)定義,即輸入和輸出類型無法從函數(shù)定義看出來。那么只剩一項(xiàng)了,參數(shù)列表的長度,即參數(shù)數(shù)量。但這真的有影響嗎? 實(shí)際上,JavaScript沒有函數(shù)重載,實(shí)參比形參長的后果僅僅是沒有給實(shí)參一個(gè)別名而已。不懂?我們來看下例子: function add(num1, num2) {console.log(arguments); // [1, 2, 3]return num1 + num2 + arguments[2]; }; var b = add(1, 2, 3); // 6 我們可以巧妙的利用arguments對象,來達(dá)到我們的目的。我們甚至可以對上面的做個(gè)擴(kuò)展,讓它能把所有參數(shù)的和返回,即使形參列表為空。 function add() {var sum = 0;for(var count = 0, length = arguments.length; count < length; count++) {sum += arguments[count];}return sum; }; var b = add(1, 2, 3, 4); // 10 那如果相反,形參列表長度比實(shí)參列表長呢? function add(num1, num2) {console.log(num1); // 1console.log(num2); // undefinedreturn num1 + num2; }; var b = add(1); // NaN 我們可以看到,超出實(shí)參長度的形參部分,就會(huì)是undefined,從而返回我們并不想要的結(jié)果(NaN表示應(yīng)該是個(gè)number類型結(jié)果卻是其他類型)。我們可以稍作修改: function add(num1, num2) {num2 = num2 || 0;return num1 + num2; }; var b = add(1); // 1 利用邏輯操作符的特性來將形參實(shí)例化,保證使用時(shí)形參不為undefined。當(dāng)然,這樣也有個(gè)別問題,如果傳入的實(shí)參邏輯值也是false(例如0、undefined、null)等等,我們就需要用全等符號(hào)進(jìn)行判斷了,在此例中不做要求。

caller和callee

這兩個(gè)對象,是用于判斷函數(shù)調(diào)用和執(zhí)行的對象函數(shù)的。其中,arguments.callee返回當(dāng)前正在執(zhí)行的函數(shù),func.caller返回函數(shù)的調(diào)用體所在函數(shù)。而arguments.caller永遠(yuǎn)返回undefined。如果調(diào)用函數(shù)是在全局進(jìn)行,那么func.caller將返回null。注意,在嚴(yán)格模式下這兩個(gè)對象將被禁用。 我們舉剛才的一個(gè)代碼為例: function getAbs(num) {function isNegative(num) {console.log(isNegative.caller); // getAbsconsole.log(arguments.callee); // isNegativereturn num < 0;}return isNegative(num) ? -num : num; } var a = getAbs(-1); 你可以將這段代碼運(yùn)行一下,會(huì)發(fā)現(xiàn),arguments.callee永遠(yuǎn)指向函數(shù)本身,而函數(shù)名.caller將指向調(diào)用該函數(shù)的代碼所在函數(shù),例如本例中即為getAbs。不過如果通過函數(shù)名.caller來尋找的話,耦合度太高。我們可以把兩個(gè)結(jié)合起來, function getAbs(num) {function isNegative(num) {console.log(arguments.callee)console.log(arguments.callee.caller)return num < 0;}return isNegative(num) ? -num : num; } var a = getAbs(-1); 有人問這個(gè)有什么用?這個(gè)嚴(yán)格的來說不是太有用,而且其安全性有問題,否則嚴(yán)格模式也不會(huì)禁用掉這兩個(gè)對象了。但說沒用也是不可能的,要不然也不會(huì)出現(xiàn)這兩個(gè)東西了。 首先,這個(gè)在調(diào)試的時(shí)候特別有效,可以幫我們理清代碼執(zhí)行順序,或者尋找bug; 其次,可以用這兩個(gè)變量實(shí)現(xiàn)一些花哨的技巧,例如我們實(shí)現(xiàn)斐波那契數(shù),正常做法是這樣: function fib(num) {if(num == 1 || num == 2) {return 1;}return fib(num - 1) + fib(num - 2); } var b = fib(6); // 8 但是這樣的壞處在于我們?nèi)绻膫€(gè)函數(shù)名,我們將同時(shí)修改三個(gè)地方(調(diào)用的暫時(shí)不論)。我們可以用我們剛學(xué)到的東西來解決這個(gè)問題: function fib(num) {if(num == 1 || num == 2) {return 1;}return arguments.callee(num - 1) + arguments.callee(num - 2); } var b = fib(6); // 8 但是,投機(jī)取巧也是有其弊端的,這會(huì)讓別人在看你的代碼的時(shí)候很費(fèi)勁。用不用,取決于具體情況。

轉(zhuǎn)載于:https://www.cnblogs.com/smght/p/4369549.html

總結(jié)

以上是生活随笔為你收集整理的JavaScript快速入门(四)——JavaScript函数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。