摘要:結果為結果為不過,提供了對象,該對象可以模擬函數重載的現象。默認名字的函數被稱之為匿名函數。提供專門的讀寫變量的函數避免全局污染閉包的應用利用閉包保護共享的局部變量,提供專門的讀寫變量的函數
Function與函數
函數是一段JavaScript代碼,它只定義一次,但可能被執(zhí)行或調用多次
Function類型是JavaScript提供的引用類型之一,通過Function類型創(chuàng)建Function對象
在JavaScript中,函數也是以對象的形式存在的。每個函數都是一個Function對象
函數名,本質就是一個變量名,是指向某個Function對象的引用
function fn(){ console.log("前端"); } console.log(fn instanceof Function);//true構造函數
在JavaScript中,函數除了可以通過函數定義語句或字面量表達式兩種方式定義之外,還可以通過Function類型進行定義
var fn=new Function("num1","num2","var sum = num1+num2;return sum");
通過Function類型定義函數的效率遠不如通過函數定義語句或字面量表達式兩種方式定義
目前,定義函數具有三種方式,這三種方式之間存在一定差別
函數定義語句:函數名被聲明提前,不存在效率問題
字面量表達式:函數體固定,無法動態(tài)執(zhí)行,不存在效率問題
Function類型定義:函數體是字符串,可以動態(tài)執(zhí)行,效率低
Function的apply()方法用于調用一個函數,并且接收指定的this值,以及一個數組作為參數,其語法結構如下:
func.apply(thisArg,[argsArray])
thisArg參數:可選項,在func函數運行時使用的this值
argsArray參數:可選項,一個數組或者類數組對象,其中的數組元素將作為多帶帶的參數傳給func函數。也可以使用arguments對象作為該參數
返回值:調用該函數的返回結果
var numbers=[1,2,3,4,5]; //通過apply()方法獲取數組中最大值和最小值 var max=Math.max.apply(null,numbers); var min=Math.min.apply(null,numbers);Function的call()方法
Function的call()方法用于調用一個函數,并且接收指定的this值作為參數,以及參數列表。其語法結構如下:
func.call(thisArg,arg1,arg2,...)
thisArg參數:在func函數運行時使用的this值
arg1,arg2,...參數:指定的參數列表
返回值:調用該函數的返回結果
apply()與call()非常相似,不同之處在于提供參數的方式
//通過call()方法獲取數組中最大值和最小值 var max=Math.max.call(null,5,6,2,3,7); var min=Math.min.call(null,5,6,2,3,7);Function的bind()方法
Function的bind()方法用于創(chuàng)建一個新的函數(稱為綁定函數),并且接收指定的this值作為參數,以及參數列表,其語法結構如下:
fun.bind(thisArg[,arg1[,arg2[,...]]])
thisArg參數:當綁定函數被調用時,該參數會作為原函數運行時的this指向
arg1,arg2,...參數:當綁定函數被調用時,這些參數將置于實參之前傳遞給被綁定的方法
返回值:返回由指定的this值和初始化參數改造的原函數
Function的bind()方法示例如下:
this.x=9; var module={ x:81, getX:function(){return this.x;} }; module.getX();//返回81 var retrieveX=module.getX; retrieveX();//返回9,在這種情況下,"this"指向全局作用域 //創(chuàng)建一個新函數,將"this"綁定到module對象 var boundGetX=retrieveX.bind(module); boundGetX();//返回 81沒有重載
在其他開發(fā)語言中,函數具有一種特性,叫做重載。所謂重載,就是定義多個同名的函數,但每一個函數接收的參數的個數不同,程序會根據調用時傳遞的實參個數進行判斷,具體調用的是哪個函數。如下示例:
function add(a,b){ return a+b; } function add(a,b,c){ return a+b+c; } add(1,2);//結果為3 add(1,2,3);//結果為6
但在JavaScript中,函數是沒有重載現象的,也就是說,如果同時定義多個同名的函數,只有最后一個定義的函數是有效的。
function add(a,b){ return a+b; } function add(a,b,c){ return a+b+c; } add(1,2);//結果為NaN add(1,2,3);//結果為6
不過,JavaScript提供了arguments對象,該對象可以模擬函數重載的現象。arguments對象是函數內部的本地變量;arguments已經不再是函數的屬性了。
arguments對象可以獲取函數的所有參數,但arguments對象并不是一個數組,而是一個類數組對象(沒有數組特有的方法)
arguments對象的屬性如下所示:
callee:表示當前執(zhí)行的函數
length:表示傳遞給當前函數的參數數量
利用arguments對象實現模擬函數的重載現象,如下述示例
function doAdd(){ if(arguments.length==1){ console.log(arguments[0]+5); }else if(arguments.length==2){ console.log(arguments[0]+arguments[1]); } } doAdd(10);//輸出"15" doAdd(40,20);//輸出"60"遞歸
在一個函數的函數體內,如果想調用自身函數的話,有如下兩種方式:
通過使用自身函數名實現
通過使用arguments對象的callee屬性實現
調用自身的函數被稱之為遞歸函數,在某種意義上說,遞歸近似于循環(huán)。兩者都重復執(zhí)行相同的代碼,并且兩者都需要一個終止條件以避免無限循環(huán)或者無限遞歸。
function loop(x){ if(x>=10){return;} loop(x+1); } loop(0);
上述代碼是一個經典的遞歸函數。雖然這個函數表面看起來并沒有什么問題,如果執(zhí)行下述代碼可能會導致出錯。
var anotherLoop=loop; loop=null; anotherLoop(0);//出錯
上述代碼將函數loop()保存到另一個變量anotherLoop中,然后將loop設置為null值。當執(zhí)行anotherLoop時,一定會執(zhí)行函數loop(),而loop已經不再是一個函數,最終導致出錯
要想解決上述遞歸函數的問題,可以使用arguments對象的callee屬性替換具體的函數名
function loop(x){ if(x>=10){ return; } arguments.callee(x+1); }匿名函數
JavaScript可以將函數作為數據使用,作為函數本體,它像普通的數據一樣,不一定要有名字。默認名字的函數被稱之為匿名函數。如下示例:
function(a){return a}
匿名函數的兩種方法:
可以將匿名函數作為參數傳遞給其他函數。這樣,接收方函數就能利用所傳遞的函數來完成某些事情
可以定義某個匿名函數來執(zhí)行某些一次性任務
回調函數當一個函數作為參數傳遞給另一個函數時,作為參數的函數被稱之為回調函數
function add(a,b){ return a()+b(); } var one=function(){return 1;} var two=function(){return 2;} console.log(add(one,two));//output 3 //可以直接使用匿名函數來替代one()和two(),以作為目標函數的參數 console.log(add(function(){return 1;},function(){return 2;}));
上述代碼中,函數one()和two()都作為函數add()的參數傳遞。所以函數one()和two()都是回調函數。當將函數A傳遞給函數B,并由B來執(zhí)行A時,A就成了一個回調函數,如果A還是一個無名函數,就稱之為匿名回調函數
回調函數優(yōu)點如下:
它可以在不做命名的情況下傳遞函數(這意味著可以節(jié)省全局變量)
可以將一個函數調用操作委托給另一個函數(這意味著可以節(jié)省一些代碼編寫工作)
回調函數也有助于提升性能
自調函數所謂自調函數就是在定義函數后自行調用。如下示例:
(function(){ console.log("javascript"); })();
上述代碼的含義如下:
第一對括號的作用,放置的是一個匿名函數。
第二對括號的作用,是"立即調用"
自調函數只需將匿名函數的定義放進一對括號中,然后外面再跟一對括號即可
自調函數也可以在調用時接收參數,如下示例:
(function(name){ console.log("hello"+name+"!"); })("javascript");//hello javascript
上述代碼的含義如下:
第一個括號中的匿名函數接受一個參數
第二個括號,在調用時,向匿名函數傳遞參數內容
作為值的函數將一個函數作為另一個函數的結果進行返回,作為結果返回的函數稱之為作為值得函數
function fn(f,args){ return f(args); } function add(num){//作為值的函數 return num+10; } var result=fn(add,10); console.log(result);//20
上述代碼還可以編寫成如下方式:
function fn(args){ return function add(){ return args+10; } }
上述兩段代碼的區(qū)別在于
var f=fn(10);//function add(){return 10+10} var result=f();//20作用域鏈
很多開發(fā)語言中都具有塊級作用域,但ECMAScript5版本中并沒有跨級作用域,這經常會導致理解上的困惑。如下示例:
if(true){ var color="blue"; } console.log(color);//blue
上述代碼在if語句中定義了變量color。但該變量的作用域是全局域,原因是ECMAScript5版本中沒有塊級作用域
雖然ECMAScript5版本沒有塊級作用域,但具有函數作用域。在某個函數內部定義的變量的作用域就是該函數作用域。
function fun(){ var v="this is function"; } console.log(v);//輸出報錯
上述代碼在函數fun內部定義了變量v,該變量的作用域是fun函數作用域。所以在全局域訪問該變量時會出錯
每一段JavaScript(全局代碼或函數)都有一個與之關聯的作用域鏈。這個作用域鏈是一個對象列表或鏈表,這組對象定義了這段代碼"作用域中"的變量。如下示例:
var a=1; //在全局域中只能訪問變量a function f(){ //在f函數作用域中可以訪問變量a和b var b=2; }閉包
JavaScript允許函數嵌套,并且內部函數可以訪問定義在外部函數中的所有變量和函數,以及外部函數能訪問的所有變量和函數。但是,外部函數卻不能夠訪問定義在內部函數中的變量和函數。
當內部函數以某一種方式被任何一個外部函數作用域訪問時,一個閉包就產生了
閉包就是該函數能使用函數外定義的變量
如下代碼就是一個最簡單形式的閉包結構:
var b; function f(){ var a="a"; b=function(){ return a+"b"; } return a; } //測試 console.log(f());//a console.log(b());//ab
閉包的特點與作用
閉包的特點:
局部變量:在函數中定義有共享意義(如:緩存、計數器等)的局部變量。(注意:定義成全局變量會對外造成污染)
內部函數:在函數(f)中聲明有內嵌函數,內嵌函數(g)對函數(f)中的局部變量進行訪問
外部使用:函數(f)向外返回此內嵌函數(g),外部可以通過此內嵌函數持有并訪問聲明在函數(f)中的局部變量,而此變量在外部是通過其他途徑無法訪問的
閉包的作用
提供可共享的局部變量
保護共享的局部變量。提供專門的讀寫變量的函數
避免全局污染
閉包的應用
利用閉包保護共享的局部變量,提供專門的讀寫變量的函數
var getValue,setValue; (function(){ var secret=0; getValue=function(){ return secret; }; setValue=function(v){ secret=v; } })();
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/108202.html
摘要:字面形式允許你在不需要使用操作符和構造函數顯式創(chuàng)建對象的情況下生成引用值。操作符以一個對象和一個構造函數作為參數鑒別數組有前一小結可以知道鑒別數組類型可以使用。屬性是函數獨有的,表明該對象可以被執(zhí)行。這種函數被稱為匿名函數。 引子: 1.JavaScript 中的變量類型和類型檢測 1.1原始類型 1.2引用類型 1.3內建類型的實例化 1.4函數的字面形式 1.5正則表達式的字...
摘要:中的數據類型及其檢測數據類型基本類型引用類型類型檢測只能檢測基本數據類型,對于還有一個用于檢測某個對象的原型鏈是否包含某個構造函數的屬性適用于檢測對象,它是基于原型鏈運作的屬性返回一個指向創(chuàng)建了該對象原型的函數引用,該屬性的值是哪個函數本身 JavaScript中的數據類型及其檢測 1. 數據類型 1.1 基本類型 Number String Boolean Null Undefin...
摘要:類型與函數的概念函數這樣的一段代碼它只定義一次但是可能被執(zhí)行或調用多次類型是提供的引用類型之一通過類型創(chuàng)建對象在中函數也是對象的形式存在注意每個函數都是以個對象與函數函數聲明方式示例代碼一笑一人生字面量方式示例代碼一花一世界判斷函數是否為類 Function類型 Function與函數的概念 函數這樣的一段JavaScript代碼,它只定義一次,但是可能被執(zhí)行或調用多次 Functi...
摘要:用和包裹的內容,稱為字符串。關系運算符用于進行比較的運算符。強制依賴于,非強制依賴于。使用場合全局環(huán)境構造函數對象的方法閉包閉包是指有權訪問另一個函數作用域中的變量的函數。所有全局對象函數以及變量均自動成為對象的成員。 1 什么是JavaScript JavaScript一種直譯式腳本語言,一種基于對象和事件驅動并具有安全性的客戶端腳本語言;也是一種廣泛應用客戶端web開發(fā)的腳本語言。...
摘要:學習目標掌握編程的基本思維掌握編程的基本語法我們先來學習基礎,后續(xù)會講解高級。語句基本語法當循環(huán)條件為時,執(zhí)行循環(huán)體,當循環(huán)條件為時,結束循環(huán)?;A語法循環(huán)體循環(huán)條件代碼示例初始化變量循環(huán)體自增循環(huán)條件語句和一般用來解決無法確認次數的循環(huán)。 學習目標: 掌握編程的基本思維 掌握編程的基本語法 我們先來學習JavaScript基礎,后續(xù)會講解JavaScript高級。 重點內容 變...
摘要:學習目標掌握編程的基本思維掌握編程的基本語法我們先來學習基礎,后續(xù)會講解高級。語句基本語法當循環(huán)條件為時,執(zhí)行循環(huán)體,當循環(huán)條件為時,結束循環(huán)?;A語法循環(huán)體循環(huán)條件代碼示例初始化變量循環(huán)體自增循環(huán)條件語句和一般用來解決無法確認次數的循環(huán)。 學習目標: 掌握編程的基本思維 掌握編程的基本語法 我們先來學習JavaScript基礎,后續(xù)會講解JavaScript高級。 重點內容 變...
閱讀 2417·2021-08-18 10:21
閱讀 2526·2019-08-30 13:45
閱讀 2158·2019-08-30 13:16
閱讀 2117·2019-08-30 12:52
閱讀 1366·2019-08-30 11:20
閱讀 2627·2019-08-29 13:47
閱讀 1626·2019-08-29 11:22
閱讀 2763·2019-08-26 12:11