函數(shù)的聲明
- function關(guān)鍵字
- 可選名稱(有效的Javascript標識符)
- 括號內(nèi)部伦意,一個以逗號分隔的參數(shù)列表(有效的Javascript標識符竖般,列表可以為空)
- 函數(shù)體,包含在大括號內(nèi)的一系列Javascript語句(函數(shù)體可以為空)
//在全局作用域下定義一個函數(shù)
function a(){}
console.log(typeof window.a==="function"); // ture window對象上的同名屬性會引用這個函數(shù)
console.log(a.name==="a"); // true 所有函數(shù)都有一個name屬性届垫,保存該函數(shù)名稱的字符串
//創(chuàng)建一個匿名函數(shù)并賦值給變量b
var b = function (){};
console.log(typeof window.b==="function"); // ture
console.log(b.name==="b"); // true 在舊瀏覽器下這樣定義的函數(shù)的name屬性為空或者undefined
//創(chuàng)建一個匿名函數(shù)并引用到window對象的一個屬性
window.c=function(){};
console.log(typeof window.c==="function"); // true
console.log(c.name===""); // true 在舊瀏覽器下這樣定義的函數(shù)的name屬性為undefined
//在全局作用域下創(chuàng)建outer函數(shù)释液,并在內(nèi)部創(chuàng)建inner函數(shù)
function outer(){
console.log(typeof inner==="function"); // true 在inner創(chuàng)建之前可以訪問到inner
function inner(){}
console.log(typeof inner==="function"); // true 在inner創(chuàng)建之后可以訪問到inner
console.log(typeof window.inner==="undefined"); // true inner沒有被綁定到全局對象上去
}
//創(chuàng)建一個函數(shù)并引用到window對象的一個屬性
window.e=function d(){};
console.log(e.name==="d"); // true 這樣創(chuàng)建的函數(shù)只能使用e來調(diào)用,但它的name屬性是函數(shù)本身的字面量名稱
作用域和函數(shù)
函數(shù)可以在其作用域范圍內(nèi)提前被引用装处,但變量不行误债。
函數(shù)調(diào)用
- 作為函數(shù)進行調(diào)用
- 作為一個對象在對象上進行調(diào)用
- 作為構(gòu)造器進行調(diào)用浸船,創(chuàng)建一個新對象
- 通過apply()或call()方法進行調(diào)用
//定義一個包含參數(shù)的函數(shù)
function f(a,b,c){}
f(1); // 當參數(shù)數(shù)量少于定義的形參執(zhí)行函數(shù)時,1會被賦值給a寝蹈,而b李命、c會被賦值為undefined
f(1,2,3,4,5); // 當參數(shù)數(shù)量多于定義的形參執(zhí)行函數(shù)時,1,2,3會被分別賦值給a,b,c箫老,而4,5不會賦值給任何形參
所有函數(shù)調(diào)用都會傳遞兩個隱式參數(shù):arguments和this封字。
arguments參數(shù)是傳遞給函數(shù)的所有參數(shù)的一個集合,具有l(wèi)ength屬性耍鬓,可以使用for對其進行遍歷阔籽,但不是真正的Javascript數(shù)組,無法使用數(shù)組的方法牲蜀,是一個類似數(shù)組的結(jié)構(gòu)笆制,只擁有數(shù)組的某些特性。
this參數(shù)引用了與該函數(shù)調(diào)用進行隱式關(guān)聯(lián)的一個對象涣达,稱之為:函數(shù)上下文在辆。this的指向依賴于函數(shù)的調(diào)用方式,即便調(diào)用的函數(shù)相同度苔,調(diào)用的方式不一樣开缎,this的指向也會不一樣。
函數(shù) “作為函數(shù)” 調(diào)用
當一個函數(shù)以 “作為函數(shù)” 的方式進行調(diào)用時林螃,表示應(yīng)用了()操作符的表達式,并且沒有將函數(shù)作為對象的一個屬性俺泣。例如:
function a(){ return this }
a();
console.log(a()===window); // true
var b=function (){ return this };
b();
console.log(a()===window); // true
//以這種方式調(diào)用時疗认,函數(shù)的上下文是全局上下文window對象,及this的指向為window對象
函數(shù) “作為方法” 調(diào)用
當一個函數(shù)以 “作為方法” 的方式進行調(diào)用時伏钠,表示函數(shù)被賦值給一個對象的屬性横漏,并使用引用該函數(shù)的屬性進行調(diào)用,例如:
var a={};
a.b=function (){ return this };
a.b(); // 以這種方式調(diào)用時熟掂,函數(shù)的上下文是當前對象
console.log(a.b()===a); // ture
其實函數(shù) “作為函數(shù)” 的調(diào)用方式是 “作為方法” 調(diào)用方式的一種特殊情況缎浇。 “作為函數(shù)” 的調(diào)用時,函數(shù)其實是綁定在window對象上的赴肚,window對象就是當前函數(shù)的上下文素跺。省略了window對象調(diào)用的方式,直接使用函數(shù)字面量進行調(diào)用誉券。
面向?qū)ο笞兂傻幕靖拍钪恢秆幔褪俏覀兛梢栽谌我夥椒ㄖ校ㄟ^this的指向來引用該方法所屬的對象踊跟。
函數(shù)作為構(gòu)造器調(diào)用
function A(){ this.b=function(){ return this }}
var c=new A(); // 在函數(shù)調(diào)用前使用new關(guān)鍵字表示函數(shù)作為構(gòu)造器進行調(diào)用
console.log(c.b()===c); // true 構(gòu)造函數(shù)創(chuàng)建的實例中this指向當前對象踩验。
作為構(gòu)造器調(diào)用時,會發(fā)生以下行為:
- 創(chuàng)建一個新的空對象。
- 將新對象的this參數(shù)傳遞給構(gòu)造器函數(shù)箕憾,從而新對象的函數(shù)上下文成為構(gòu)造器的函數(shù)上下文牡借。
- 如果沒有顯示的返回值,則新對象作為構(gòu)造器的返回值進行返回(任何干擾這種意圖的都不適合作為構(gòu)造器)袭异。
一般的函數(shù)和方法以小寫字母開頭钠龙,構(gòu)造器函數(shù)以大寫字母開頭。
使用apply()和call()方法進行調(diào)用
Javascript中函數(shù)也可以像對象一樣擁有方法和屬性扁远,每個函數(shù)都有apply()和call()方法俊鱼。
通過apply()調(diào)用函數(shù),需要傳入兩個參數(shù)畅买,一個是作為函數(shù)上下文的對象并闲,另一個是函數(shù)參數(shù)所組成的數(shù)組。call()方法與之類似谷羞,唯一不同的是call()方法給函數(shù)傳入的是參數(shù)列表帝火,而不是將所有參數(shù)作為一個數(shù)組傳入。
function x(a,b){
this.y=a+b;
}
var a={};
var b={};
x.apply(a,[1,2]);
x.call(b,1,2);
console.log(a.y); // 3 此時x函數(shù)中的this被綁定為a對象
console.log(b.y); // 3 此時x函數(shù)中的this被綁定為b對象
Javascript是函數(shù)式編程語言湃缎,函數(shù)式程序的構(gòu)件塊而不是命令式語句犀填。
//一般的命令式編程
function (list){
for(var i=0;i<list.length;i++){
/* 每一項需要執(zhí)行的代碼 */
}
}
//函數(shù)式編程
for(var i=0;i<list.length;i++){
fun(list[n]);
}