學(xué)好js,這些js函數(shù)概念一定要知道【推薦】
函數(shù)創(chuàng)建方式
1.聲明方式 例如:function consoleTip (){ console.log("tip!"); }
2.表達(dá)式方式 例如:var consoleTip = function(){ console.log("tip!"); }
兩種方式的區(qū)別:
1.表達(dá)式方式適合用來定義只使用一次的函數(shù),聲明方式定義的函數(shù)沒有這個(gè)限制,當(dāng)然也不是絕對(duì)的,這個(gè)區(qū)別只適用于編碼規(guī)范上;
2.聲明方式定義的函數(shù)可以在函數(shù)調(diào)用之前定義也可以在函數(shù)調(diào)用之后定義,而表達(dá)式方式定義的函數(shù)只能在函數(shù)調(diào)用之前定義;
函數(shù)參數(shù)
函數(shù)參數(shù)包括形參,實(shí)參,形參就是函數(shù)定義時(shí)的參數(shù);實(shí)參就是函數(shù)調(diào)用時(shí)傳入的參數(shù)。由于js是弱類型語言,所以js函數(shù)的形參不指定類型。
js函數(shù)的形參和實(shí)參個(gè)數(shù)可以不一致。形參個(gè)數(shù)小于實(shí)參時(shí),未傳的形參值都是undefined,注意形參可以指定默認(rèn)值,但是只能在函數(shù)體內(nèi)部指定;形參個(gè)數(shù)小于實(shí)參時(shí),在函數(shù)體內(nèi)引用多余實(shí)參,必須通過實(shí)參對(duì)象arguments來獲取實(shí)參,在函數(shù)體內(nèi)部arguments就是實(shí)參對(duì)象的引用,并且此時(shí)的實(shí)參對(duì)象是一個(gè)數(shù)組對(duì)象,數(shù)組對(duì)象每一項(xiàng)對(duì)應(yīng)著函數(shù)調(diào)用時(shí)傳入的參數(shù)。
PS:實(shí)參對(duì)象有兩個(gè)特殊屬性callee和caller,其中callee屬性代指當(dāng)前正在執(zhí)行的函數(shù),caller屬性代指調(diào)用當(dāng)前正在執(zhí)行的函數(shù)的函數(shù),caller屬性不是標(biāo)準(zhǔn)屬性,不是所有瀏覽器都支持。使用callee屬性的典型例子就是匿名函數(shù)的遞歸調(diào)用,例如定義一個(gè)階乘函數(shù):
var fact = function(x){
if(x <= 1) {
return 1;
}else{
return arguments.callee(x-1)*x;
}
};
函數(shù)作用域
在函數(shù)中聲明的變量(包括函數(shù)形參)在整個(gè)函數(shù)體內(nèi)都是可見的,包括嵌套的函數(shù)中,在函數(shù)外部是不可見的;函數(shù)體內(nèi)部定義的變量會(huì)覆蓋同名的全局變量;
函數(shù)作用域中有個(gè)特性很重要,就是“聲明提前”,意思就是在函數(shù)內(nèi)部任意位置聲明的變量,在函數(shù)體內(nèi)部任意位置都是可見的,這是因?yàn)閖s引擎在預(yù)編譯js時(shí)會(huì)把函數(shù)中所有的變量聲明都提前至函數(shù)體頂部。
例如:
var scope = "outter";
!function(){
console.log(scope); //undefined
var scope = "inner";
console.log(scope); //inner
}();
console.log(scope); //outter
說明:
undefined 由于函數(shù)作用域的聲明提前特性,這里的scope已經(jīng)在函數(shù)頂部聲明,但是沒有被賦值,所以scope值為undefined
inner scope在函數(shù)體內(nèi)部聲明,并且有賦值
outter 函數(shù)體內(nèi)部定義的變量會(huì)覆蓋同名的全局變量,但是不影響全局變量的值
構(gòu)造函數(shù)
構(gòu)造函數(shù)的用處就是用來初始化新創(chuàng)建的對(duì)象,例子:var ary = new Array();
構(gòu)造函數(shù)與普通函數(shù)的區(qū)別:
1.函數(shù)命名上有區(qū)別,構(gòu)造函數(shù)命名時(shí)通常是首字符大寫,普通函數(shù)命名時(shí)首字符小寫;
2.調(diào)用方式的區(qū)別,構(gòu)造函數(shù)是通過new關(guān)鍵字調(diào)用,而普通函數(shù)直接調(diào)用。
立即執(zhí)行函數(shù)
把函數(shù)定義和函數(shù)執(zhí)行結(jié)合到一起就是立即執(zhí)行函數(shù),也叫自執(zhí)行函數(shù)。
這里需要注意兩點(diǎn):1.函數(shù)定義僅限于表達(dá)式方式定義的函數(shù);2.函數(shù)執(zhí)行實(shí)際上就是對(duì)函數(shù)表達(dá)式做一次運(yùn)算,所以一元運(yùn)算符都可以讓函數(shù)執(zhí)行。
這樣的話,立即執(zhí)行函數(shù)就會(huì)有多種寫法:
(function(){console.log("IIFE");}());
(function(){console.log("IIFE");})();
!function(){console.log("IIFE");}();
void function(){console.log("IIFE");}();
~function(){console.log("IIFE");}();
....
立即執(zhí)行函數(shù)可以接受參數(shù),上面的寫法都是可以的,但是編碼規(guī)范推薦第一種寫法,jQuery庫使用的就是第一種寫法。
那么自執(zhí)行函數(shù)的用處有哪些呢?總結(jié)起來常用也就兩種:1.保存參數(shù)上下文環(huán)境;2.作為命名空間。
用處1的適用場(chǎng)景:循環(huán)中執(zhí)行異步函數(shù),并且函數(shù)參數(shù)隨循環(huán)變化。
/**
* 實(shí)例一
* 錯(cuò)誤寫法,因?yàn)閖Query的post方法是異步的,循環(huán)十次,post方法并行跑十次,
* 循環(huán)比post方法執(zhí)行要快,最終傳過去的i值都變成了10,即服務(wù)端收到index的都是10
*/
for(var i=0; i<10; i++){
$.post(url,{index:i},function(){});
}
/**
* 正確寫法,這樣對(duì)于循環(huán)體中的立即執(zhí)行函數(shù)來說,每次循環(huán)得到的參數(shù)都不同。立即執(zhí)行函數(shù)
* 每執(zhí)行一次都會(huì)創(chuàng)建一個(gè)函數(shù)上下文環(huán)境,在這個(gè)上下文環(huán)境中的變量值不受外界影響,
* 循環(huán)十次就會(huì)創(chuàng)建十個(gè)上下文環(huán)境,并且每個(gè)上下文環(huán)境的i值都不一樣。這樣的話,
* 雖然post方法是異步方法,但是是在每一個(gè)上下文環(huán)境中執(zhí)行的,也就是說循環(huán)十次,
* post方法在十個(gè)上下文環(huán)境中分別執(zhí)行了一次,post方法中使用的index參數(shù)每次都不一樣,
* 最終服務(wù)端收到的index值就是從0到9十個(gè)數(shù)值
*/
for(var i=0; i<10; i++){
(function(index){$.post(url,{index:index},function(){});}(i));
}
/**
* 實(shí)例二
* 錯(cuò)誤寫法,最終會(huì)輸出十個(gè)10,因?yàn)檠h(huán)體的語句會(huì)延時(shí)執(zhí)行
*/
for(var i=0; i<10; i++){
setTimeout(function(){console.log(i);},100);
}
//正確寫法,最終會(huì)輸出0到9十個(gè)數(shù)值,原理同上
for(var i=0; i<10; i++){
(function(x){setTimeout(function(){console.log(x);},100);}(i));
}
用處2的適用場(chǎng)景:你需要寫一個(gè)公共模塊,這個(gè)公共模塊在很多地方都會(huì)使用,但是要保證公共模塊中使用的變量和函數(shù)不會(huì)對(duì)其它模塊造成污染,這樣的話這個(gè)公共模塊就需要一個(gè)單獨(dú)的不同于其它模塊的命名空間。
案例1:創(chuàng)建jQuery插件,保證創(chuàng)建的jQuery插件在jQuery的命名空間內(nèi)都是有效的,這樣每個(gè)jQuery對(duì)象才可以使用。
(function($){
$.fn.changeStyle = function(colorStr){
this.css("color",colorStr);
return this;
}
}(jQuery));
案例2:創(chuàng)建一個(gè)帶有私有變量和私有方法的對(duì)象。
var obj = (function(){
var privateAttr,
publicAttr;
function _setPriAttr(){
privateAttr = "private";
}
function getPriAttr(){
return privateAttr;
}
return {
attr:publicAttr,
getAttr:function(){
getPriAttr();
}
}
}());
通過這種方式創(chuàng)建的對(duì)象,利用立即執(zhí)行函數(shù)的return語句對(duì)外暴露屬性以及方法,并且可以保證沒有對(duì)外暴露對(duì)象的屬性和方法,在對(duì)象外邊是無法訪問到的。
總結(jié):其實(shí)用處1和用處2的原理都是一樣的,都是利用了函數(shù)作用域的概念,請(qǐng)仔細(xì)體會(huì)。
參考資料: js權(quán)威指南
以上就是本文的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時(shí)也希望多多支持腳本之家!
相關(guān)文章
IE FF OPERA都可用的彈出層實(shí)現(xiàn)代碼
多瀏覽器的彈出層效果核心代碼。需要的朋友可以測(cè)試下這個(gè)是從正在使用的網(wǎng)站中扒下來的。2009-09-09
jquery實(shí)現(xiàn)右側(cè)欄菜單選擇操作
這篇文章主要為大家詳細(xì)介紹了jquery實(shí)現(xiàn)右側(cè)欄菜單選擇操作,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-03-03
javascript單張多張圖無縫滾動(dòng)實(shí)例代碼
在本篇文章里小編給大家分享的是關(guān)于javascript單張多張圖無縫滾動(dòng)實(shí)例代碼和實(shí)例,需要的朋友們可以參考下。2020-05-05
JS實(shí)現(xiàn)多級(jí)菜單中當(dāng)前菜單不隨頁面跳轉(zhuǎn)樣式而發(fā)生變化
本文介紹了JQuery巧妙實(shí)現(xiàn)多級(jí)菜單中當(dāng)前菜單不隨頁面跳轉(zhuǎn)樣式發(fā)生變化,實(shí)現(xiàn)方法非常簡(jiǎn)單,感興趣的朋友一起看看吧2017-05-05
Electron 使用 Nodemon 配置自動(dòng)重啟的方法
在Electron開發(fā)過程中,每次代碼修改后需手動(dòng)重新啟動(dòng)應(yīng)用,這一過程可以通過引入Nodemon工具自動(dòng)化,Nodemon能夠監(jiān)測(cè)文件變化并自動(dòng)重啟服務(wù)器,本文給大家介紹Electron 使用 Nodemon 配置自動(dòng)重啟,感興趣的朋友一起看看吧2024-09-09
JS實(shí)現(xiàn)十分鐘倒計(jì)時(shí)代碼實(shí)例
在本篇文章里我們給大家分享了關(guān)于JS實(shí)現(xiàn)十分鐘倒計(jì)時(shí)的相關(guān)實(shí)例代碼,有需要的朋友們可以學(xué)習(xí)下。2018-10-10
javascript中的toFixed固定小數(shù)位數(shù) 簡(jiǎn)單實(shí)例分享
這篇文章介紹了toFixed固定小數(shù)位數(shù)的簡(jiǎn)單例子,有需要的朋友可以參考一下2013-07-07
ES6中Set和Map數(shù)據(jù)結(jié)構(gòu)的簡(jiǎn)單講解
大家心里是否產(chǎn)生過這樣的疑問,JS中既然已經(jīng)有對(duì)象這種數(shù)據(jù)結(jié)構(gòu),我們?yōu)槭裁催€要再單獨(dú)去使用Set或者M(jìn)ap呢?下面這篇文章主要給大家介紹了關(guān)于ES6中Set和Map數(shù)據(jù)結(jié)構(gòu)的相關(guān)資料,需要的朋友可以參考下2022-08-08

