1.定義:
**通常:function fname(arg) {...}
**直接量法: var fvar=function(arg) {...} --無函數名
var fvar=function fname(arg) {...} ----有函數名(應用場景:調用自身的遞歸函數)
**對象法:var myFunction=new Function("a","b","return a+b"); ----js裏函數即對象
直接量法爲js表達式創建,而不是語句創建,所以更靈活了。尤其適用於那些只使用一次且無需命名的函數,但個人認爲不指定fName創建一個無名函數,有的時候就沒有任何意義。因爲可以用表達式來代替,如下面的第2個例子。直接量法定義的例子如下:
f[0]=function(x) {...} //define and store it;invoke:f[0](5)
a.sort(function(x,y) {return x+y;}) //define and pass it to another
var b=(function(x){return x*x;})(10) //define and invoke
2.js裏函數即對象
(1)函數對象和其他內部對象的關係
typeof返回“function”的對象都是函數對象。也稱這樣的對象爲構造器(constructor)
alert(typeof(Function))); //構造器
alert(typeof(new Function())); //構造器
alert(typeof(Array)); //構造器
alert(typeof(Object)); //構造器
alert(typeof(new Array()));
alert(typeof(new Date()));
alert(typeof(new Object()));
前面4條語句都會顯示“function”,而後面3條語句則顯示“object”,可見new一個function實際上是返回一個函數。這與其他的對象有很大的不同。其他的類型Array、Object等都會通過new操作符返回一個普通對象。管函數本身也是一個對象,但它與普通的對象還是有區別的,因爲它同時也是對象構造器。(2)運用
函數====參數
function func1(theFunc){
theFunc();
}
function func2(){
alert("ok");
}
func1(func2);
函數====數據(變量的值、對象屬性的值、數組的元素.....)
function fs(x) {...}
var c=fs;
var d=c(4);
var o=new Object();
o.name=function(x) {return x*x;}
o.name(16);
var a=new Array(3);
a[0]=function(x) {return x*x;}
a[1]=20;
a[2]=a[0](a[1])
函數====方法( 調用方法的對象成爲關鍵字this值)
事實上,將函數作爲參數傳遞,或者是將函數賦值給其他變量是所有事件機制的基礎
3.函數參數
(1)隱含參數對象:arguments
當進行函數調用時,除了指定的參數外,還創建一個隱含的對象——arguments。arguments是一個類似數組但不是數組的對象,說它類似是因爲它具有數組一樣的訪問性質,可以用arguments[index]這樣的語法取值,擁有數組長度屬性length。arguments對象存儲的是實際傳遞給函數的參數,而不侷限於函數聲明所定義的參數列表。
***arguments引用獲得參數
function func(a,b){
alert(a);
alert(b);
for(var i=0;i<arguments.length;i++){
alert(arguments[i]);
}
}
func(1,2,3);
代碼運行時會依次顯示:1,2,1,2,3。因此,在定義函數的時候,即使不指定參數列表,仍然可以通過arguments引用到所獲得的參數,這給編程帶來了很大的靈活性***arguments對象的屬性callee,它表示對函數對象本身的引用,這有利於實現無名函數的遞歸或者保證函數的封裝性
詳分析見 http://blog.csdn.net/beiji_nanji/article/details/7585156
***arguments對象的屬性length,實參的長度(函數的屬性length,表示函數定義時的形參個數)
(2)函數可選參數
格式: function fname(arg1,/* optional */ a)
(3) 可變長度參數列表
格式:
function fname(/* ... */) 或 function fname()
參數用arguments來取
function fname(/* ... */) {return arguments.length}
fname(1,2,3) //3
function fname1() {return arguments.length}
fname1(1,2,3) //3
(4) 對象作爲函數參數
略
4.函數的屬性
(1) length,表示函數定義時的形參個數(arguments對象的屬性length,實參的長度)
(2) prototype--對象原型
**在js中模擬類:
#支持對象的數據類型,但是沒有類的正式概念。它通過構造函數,及其原型對象來模擬來近似的模擬類
#但是它是一種真正的面向對象的語言,它採用的是原型的繼承,而不是類的繼承。
(#類名首字母寫,對象名用小寫字母--編程慣例哦)
**一個對象的原型就是它的構造函數的prototype屬性的值,當函數被定義的時候,prototype屬性自動創建和初始化,初始化的值叫“原型對象”
**“原型對象”的用法:放置方法和不變屬性(或爲通用屬性)
**使用“原型對象”的好處:a.顯著減少每個對象所需的內存數量,因爲對象可以繼承原型的很多屬性 b.在對象創建後添加到原型中的屬性,對象也可以繼承後加的屬性
**object.hasOwnPropery('propertyname'):區分繼承的屬性和常規的屬性
**屬性的讀取:“先常規,再繼承,再創建”。先查找常規的,找到就不往下找了,如果常規沒找到,就去繼承(原型)裏找,原型裏也沒有,就自動創建一個。
**更多:http://blog.csdn.net/chaojie2009/article/details/6719353
function rex(w,h){
this.width=w;
this.height=h;
}
rex.prototype.area=function(){return this.width*this.height;} //要顯示的用this來訪問屬性,與java c不同(可以省略)。或用下面的形式。
//rex.prototype.area=function(){ with(this){return width*height;}}
var r=new rex(3,4);
var a=r.area();
(3) 定義函數自己的屬性
當函數需要使用一個在調用過程中都保持不變的值時,使用Function對象的屬性比定義一個全局變量更加方便,因爲全局變量會使命名空間變得散亂。
var fname.count=0 //可在函數前申明
function fname(){
return fname.count++;
}
5.函數對象的2個方法: apply和call
詳分析見http://blog.csdn.net/beiji_nanji/article/details/7585105
6.函數裏的this指針
this指針是面向對象程序設計中的一項重要概念,它表示當前運行的對象。在實現對象的方法時,可以使用this指針來獲得該對象自身的引用。
和其他面向對象的語言不同,JavaScript中的this指針是一個動態的變量,一個方法內的this指針並不是始終指向定義該方法的對象的
JavaScript中的this指針是一個動態變化的變量,它表明了當前運行該函數的對象。由this指針的性質,也可以更好的理解JavaScript中對象的本質:一個對象就是由一個或多個屬性(方法)組成的集合。每個集合元素不是僅能屬於一個集合,而是可以動態的屬於多個集合。這樣,一個方法(集合元素)由誰調用,this指針就指向誰。實際上,apply方法和call方法都是通過強制改變this指針的值來實現的,使this指針指向參數所指定的對象,從而達到將一個對象的方法作爲另一個對象的方法運行。