1. 函數(shù)名。
函數(shù)即對(duì)象,函數(shù)名是指針(指針變量)。
每個(gè)函數(shù)都是Function類型的實(shí)例。
函數(shù)名是指針,不會(huì)與某個(gè)函數(shù)綁定。也就是說,函數(shù)名(實(shí)際是個(gè)存了指針的變量)里的指針可以被修改,而函數(shù)也可以有多個(gè)函數(shù)名。
函數(shù)名本身就是變量,也可以作為值來使用,所以一個(gè)函數(shù)可以作為另一個(gè)函數(shù)的參數(shù),也可以作為返回值。
注意,使用不帶圓括號(hào)的函數(shù)名是訪問函數(shù)指針,而非調(diào)用函數(shù)。要訪問某個(gè)函數(shù)而不執(zhí)行函數(shù)的話,直接訪問不帶小括號(hào)的函數(shù)名即可。
2.函數(shù)屬性和方法。
函數(shù)內(nèi)部有:2個(gè)特殊對(duì)象arguments和this;4個(gè)屬性caller、length、prototype、constructor;9個(gè)方法call()、apply()、bind()、valueOf()、toLocaleString()、toString()、isPrototypeOf()、hasOwnProperty()、propertyIsEnumerable()。
(1).arguments。
這是一個(gè)對(duì)象,用來訪問維護(hù)函數(shù)參數(shù)的數(shù)組。
訪問數(shù)組元素用[],arguments[0]是函數(shù)的第一個(gè)參數(shù)。訪問數(shù)組長度用length屬性(不是方法),arguments.length可知命名參數(shù)的個(gè)數(shù)。
arguments永遠(yuǎn)與對(duì)應(yīng)的命名參數(shù)同步,包括值和個(gè)數(shù)。
arguments對(duì)象與命名參數(shù)雖然同步,但存儲(chǔ)空間是獨(dú)立的。
沒有傳遞值的命名參數(shù)被自動(dòng)賦予undefined值。
arguments的length由調(diào)用函數(shù)時(shí)傳入的參數(shù)數(shù)目決定,而不是定義函數(shù)時(shí)命名參數(shù)的個(gè)數(shù)。
所以,如果命名參數(shù)有兩個(gè),但輸入?yún)?shù)只有一個(gè),則arguments.length為1,且手動(dòng)賦值arguments[1]=12;也不會(huì)傳給第二個(gè)命名參數(shù),第二個(gè)命名參數(shù)的值還是默認(rèn)的undefined。例如:
function sum(num1, num2){
??? arguments[1]=120;
??? return? num1+num2;
}
sum(10);//輸出NaN,因?yàn)閚um2的值為undefined
分析:
sum.length值為2。命名參數(shù)有兩個(gè),num1和num2,所以函數(shù)sum期望在被調(diào)用時(shí)輸入兩個(gè)參數(shù)。
arguments.length的值為1。sum函數(shù)被調(diào)用時(shí)傳入的參數(shù)只有一個(gè),所以為1。
num2的值為undefined。調(diào)用sum函數(shù)時(shí),傳入的參數(shù)只有一個(gè),所以num2為默認(rèn)的undefined。即使函數(shù)中有arguments[1]=120,也無法傳給num2。
sum(10)返回NaN,因?yàn)閚um1為10,num2為undefined,10+undefined得到NaN。
arguments的屬性和方法:
length,屬性,獲取命名參數(shù)個(gè)數(shù)。
callee,屬性,是一個(gè)指針,指向本arguments對(duì)象的函數(shù)??捎糜谙o密耦合(例如,階乘函數(shù)遞歸方法優(yōu)化)。
caller,屬性,非嚴(yán)格模式下始終為undefined,嚴(yán)格模式下訪問它會(huì)導(dǎo)致錯(cuò)誤。
(2). this。
this引用的是函數(shù)執(zhí)行的環(huán)境對(duì)象。
在全局作用域調(diào)用函數(shù)時(shí),this對(duì)象引用的是window。(執(zhí)行環(huán)境為全局環(huán)境)
(3).caller。
函數(shù)的caller屬性保存調(diào)用當(dāng)前函數(shù)的函數(shù)引用。(實(shí)踐經(jīng)驗(yàn),不知對(duì)否)需要在本函數(shù)內(nèi)使用時(shí)才返回當(dāng)前本函數(shù)的函數(shù)引用(理解為“保存此時(shí)調(diào)用本函數(shù)的函數(shù)名”)。例如,
function myFunction(a,b){
???? add10(a);
???? alert(add10.caller);//最后彈出,輸出為“null”。
???? return a*b;
}
function add10(c){
???? alert(arguments.callee.caller);//第二個(gè)彈出,
??????????????????????????????????????????????? //輸出myFunction()的定義語句。即本程序前5行。
???? alert(add10.caller);//第三個(gè)彈出,輸出與第二個(gè)一樣
? ?? return c+10;
}
alert(add10.caller);//首先彈出,輸出“null”
(4). length。
表示函數(shù)期望在被調(diào)用時(shí)傳入的參數(shù)個(gè)數(shù),其實(shí)也就是定義時(shí)命名參數(shù)的個(gè)數(shù)。
與arguments對(duì)象的length不同,函數(shù)的length是期望在被調(diào)用是傳入的參數(shù)個(gè)數(shù)(期望個(gè)數(shù)),而arguments.length是實(shí)際調(diào)用時(shí)傳入?yún)?shù)的個(gè)數(shù)(實(shí)際個(gè)數(shù))。
(5). prototype。
(6).constructor。從對(duì)象Object那里繼承來的屬性。
(7).apply()。
接收兩個(gè)參數(shù),第一個(gè)是運(yùn)行函數(shù)的作用域(即設(shè)置本函數(shù)的this值);第二個(gè)是函數(shù)的參數(shù)數(shù)組(可以是Array實(shí)例,也可以是arguments對(duì)象)。
設(shè)置函數(shù)體內(nèi)this對(duì)象的值,使得函數(shù)在特定的作用域調(diào)用。例如,
function? sum(num1, num2){ return num1+num2;}
function?? callSum(num1, num2){
??? return?? sum.apply(this, arguments);//這個(gè)和argumentsthis是callSum函數(shù)的。
}
(8).call()。
與apply()一樣的用途,只是call接受參數(shù)的方式不同,第一個(gè)參數(shù)為運(yùn)行函數(shù)的作用域(即設(shè)置本函數(shù)的this值);后面的參數(shù)為函數(shù)的所有參數(shù)(必須明確傳入所有參數(shù),所有)。
apply()和call()的真正用途其實(shí)是擴(kuò)充函數(shù)的作用域。例如,
window.color="red";
var o={color:"blue"};
function? sayColor(){ alert(this.color); }
sayColor();? //"red"
sayColor.call(this);? //"red"
sayColor.call(this);? //"red"
sayColor.call(o);? //"blue"
(9).bind()。
將bind()中的值綁定給函數(shù)的this值。
例如,同樣是上述代碼,在加上如下代碼后,執(zhí)行objectSayColor函數(shù),輸出的為blue,因?yàn)閠his值綁定了o:
var objectSayColor=sayColor.bind(o);
objectSayColor();? //"blue"
(10).valueOf()。從對(duì)象Object那里繼承來的方法。
(11).toLocaleString()。從對(duì)象Object那里繼承來的方法。
(12). toString()。從對(duì)象Object那里繼承來的方法。
(13).isPrototypeOf(object)。從對(duì)象Object那里繼承來的方法。
(14). hasOwnProperty(propertyName)。從對(duì)象Object那里繼承來的方法。
(15).propertyIsEnumerable(propertyName)。從對(duì)象Object那里繼承來的方法。
1. 函數(shù)聲明。
函數(shù)使用function關(guān)鍵字聲明,在代碼執(zhí)行之前,解析器通過一個(gè)函數(shù)聲明提升的過程,讀取并將函數(shù)聲明添加到執(zhí)行環(huán)境中。
對(duì)代碼求值時(shí),JavaScript引擎在第一遍會(huì)函數(shù)聲明并將它們放到源代碼樹的頂部。所以函數(shù)調(diào)用在函數(shù)聲明之前也沒有問題。
函數(shù)表達(dá)式?jīng)]有函數(shù)聲明提升的過程,所以調(diào)用函數(shù)表達(dá)式定義的函數(shù)時(shí),必須在函數(shù)表達(dá)式的后面。
也可以將函數(shù)聲明與函數(shù)表達(dá)式同時(shí)使用,例如,var? sum=function sum(){}。但是這種語法在Safari中會(huì)導(dǎo)致錯(cuò)誤。
函數(shù)聲明與函數(shù)表達(dá)式在其他方面沒有區(qū)別。
HTML中?算定義還是聲明?
2.函數(shù)定義。
定義函數(shù)的方法有多種:
(1).使用function聲明的方式定義。
(2). 使用函數(shù)表達(dá)式定義函數(shù)。
var? sum = function(num1,num2){return? num1+num2};
(3).使用Function構(gòu)造函數(shù)定義函數(shù)(不推薦,因?yàn)檫@回導(dǎo)致解析兩次代碼,第一次解析常規(guī)代碼,第二次解析傳入構(gòu)造函數(shù)的字符串)。
Function構(gòu)造函數(shù)可以接收任意數(shù)量的參數(shù),但最后一個(gè)參數(shù)始終被看成函數(shù)體。用Function定義函數(shù)的格式,例如,
var sum=new? Function("num1", "num2", "return? num1+num2");
3.函數(shù)表達(dá)式。
4.函數(shù)參數(shù)。
函數(shù)不介意傳進(jìn)來的參數(shù)的個(gè)數(shù)和類型,即便定義的參數(shù)只有兩個(gè),也可以傳入零個(gè)、一個(gè)、兩個(gè)、三個(gè)、四個(gè)、更多個(gè)參數(shù)。
ECMScript中的函數(shù)參數(shù)在內(nèi)部用一個(gè)數(shù)組來表示的,函數(shù)接收的是這個(gè)數(shù)組,并不關(guān)心數(shù)組中是否有元素,有幾個(gè)元素。
可通過arguments對(duì)象(不是Array的實(shí)例)訪問這個(gè)數(shù)組,數(shù)組第一個(gè)元素(第一個(gè)參數(shù))用arguments[0]訪問,第二個(gè)用arguments[1]訪問。
可以通過arguments的length屬性獲知有多少個(gè)參數(shù)傳給了函數(shù),arguments.length。
arguments對(duì)象中的值與對(duì)應(yīng)命名參數(shù)一致,但是他們的內(nèi)存空間時(shí)獨(dú)立的。
沒有傳遞值的命名參數(shù)將自動(dòng)被賦予undefined值。
5.函數(shù)返回值。
函數(shù)在執(zhí)行return語句后立即退出并返回返回值,一定有返回值,沒有指定返回值時(shí)返回undefined。
6.函數(shù)自調(diào)用。
7.沒有函數(shù)重載。
沒有函數(shù)重載,如果定義了兩個(gè)同名函數(shù),則名字只屬于后面定義的函數(shù)。
為什么JS函數(shù)沒有重載?原因有兩個(gè):
(1).沒有函數(shù)簽名。其他函數(shù)通過函數(shù)簽名(傳入?yún)?shù)的類型和數(shù)量)來實(shí)現(xiàn)函數(shù)重載,但是JS函數(shù)的參數(shù)由一個(gè)數(shù)組維護(hù)(數(shù)組通過arguments對(duì)象訪問),并不介意參數(shù)了個(gè)數(shù)、類型,所以沒有重載。
(2).函數(shù)名實(shí)際上是指向函數(shù)對(duì)象的指針,與包含對(duì)象指針的其他變量沒有區(qū)別。命名多個(gè)同名函數(shù)時(shí),只是將后面的指針覆蓋前面的指針存在函數(shù)名里(函數(shù)名就像個(gè)變量一樣)。所以沒有重載。
8.Function構(gòu)造函數(shù)。
9. 函數(shù)內(nèi)部屬性。
10.函數(shù)屬性和方法。(函數(shù)即對(duì)象)
11. 箭頭函數(shù)(ES6)。
12.回調(diào)函數(shù)。
13. 函數(shù)生成器。