javascript基礎知識(30) Function函數與Object對象的關系


函數對象和其他內部對象的關系

  除了函數對象,還有很多內部對象,比如:Object、Array、Date、RegExp、Math、Error。這些名稱實際上表示一個 類型,可以通過new操作符返回一個對象。然而函數對象和其他對象不同,當用typeof得到一個函數對象的類型時,它仍然會返回字符串 “function”,而typeof一個數組對象或其他的對象時,它會返回字符串“object”。下面的代碼示例了typeof不同類型的情況: 
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操作符返回一個普通對象。盡管函數本身也是一個 對象,但它與普通的對象還是有區別的,因為它同時也是對象構造器,也就是說,可以new一個函數來返回一個對象。所有typeof返回 “function”的對象都是函數對象。也稱這樣的對象為構造器(constructor),因而,所有的構造器都是對象,但不是所有的對象都是構造器

既然函數本身也是一個對象,它們的類型是function,聯想到C++、Java等面向對象語言的類定義,可以猜測到Function類型的作用所在,那就是可以給函數對象本身定義一些方法和屬性,借助於函數的prototype對象,可以很方便地修改和擴充Function類型的定義,例如下面擴展了函數類型Function,為其增加了method1方法,作用是彈出對話框顯示"function":  

Function.prototype.method1=function(){ 
      alert("function"); 
} 
function func1(a,b,c){ 
      return a+b+c; 
} 
func1.method1(); 
func1.method1.method1(); 

注意最后一個語句:func1.method1.mehotd1(),它調用了method1這個函數對象的method1方法。雖然看上去 有點容易混淆,但仔細觀察一下語法還是很明確的:這是一個遞歸的定義。因為method1本身也是一個函數,所以它同樣具有函數對象的屬性和方法,所有對 Function類型的方法擴充都具有這樣的遞歸性質。 

  Function是所有函數對象的基礎,而Object則是所有對象(包括函數對象)的基礎。在JavaScript中,任何一個對象都是 Object的實例,因此,可以修改Object這個類型來讓所有的對象具有一些通用的屬性和方法,修改Object類型是通過prototype來完成的: 

Object.prototype.getType=function(){ 
       return typeof(this); 
} 
var array1=new Array(); 
function func1(a,b){ 
      return a+b; 
} 
alert(array1.getType()); 
alert(func1.getType()); 

上面的代碼為所有的對象添加了getType方法,作用是返回該對象的類型。兩條alert語句分別會顯示“object”和“function”。 

 將函數作為參數傳遞 
  在前面已經介紹了函數對象本質,每個函數都被表示為一個特殊的對象,可以方便的將其賦值給一個變量,再通過這個變量名進行函數調用。作為一個變量,它可以以參數的形式傳遞給另一個函數,這在前面介紹JavaScript事件處理機制中已經看到過這樣的用法,例如下面的程序將func1作為參數 傳遞給func2: 

function func1(theFunc){ 
      theFunc(); 
} 
function func2(){ 
      alert("ok"); 
} 
func1(func2); 

在最后一條語句中,func2作為一個對象傳遞給了func1的形參theFunc,再由func1內部進行theFunc的調用。事實上,將函數作為參數傳遞,或者是將函數賦值給其他變量是所有事件機制的基礎。 
例如,如果需要在頁面載入時進行一些初始化工作,可以先定義一個init的初始化函數,再通過window.onload=init;語句將其綁定到頁面載入完成的事件。這里的init就是一個函數對象,它可以加入window的onload事件列表。

Function是javascript里最常用的一個概念,javascript里的function是最容易入手的一個功能,但它也是javascript最難理解最難掌握的一個概念。

今天我們來嘗試理解Function和Object.因為這個里面有些人前期可能會搞糊塗.他們之間到底是什么關系.當然也不除外當初的我.

注意:官方定義: 在Javascript中,每一個函數實際上都是一個函數對象.

我們先來看最簡單的兩個代碼,也是最容易理解的。

function fn(){}
var obj = {}
console.log(fn instanceof Function)//true
console.log(obj instanceof Object)//true
console.log(fn instanceof Object)//true
console.log(obj instanceof Function)//false

前面兩個打印的效果,大家都容易理解。

后面 fn instanceof Object 是為true.這里也是一樣,從函數的定義來說: 在javascript中一切函數實際都是函數對象. 所以為true就不奇怪了

obj instanceof Function 為false,當然不奇怪了.因為他是一個對象,不是函數.

我們再來看一個代碼

console.log(Function instanceof Object); // true
console.log(Object instanceof Function); // true

代碼很簡單.運行結構兩個都是為true,為什么呢? 第一個用函數的定義來說,(javascript中函數實際也是一個函數對象),當然為true,那第二個呢?對象也是函數?

Object也是函數.因為Object的結構是function Object(){native code}

這種形式,很清晰的就是聲明的一個Object函數,當然就是函數了,所以兩個都是為true.

他們兩個Function和Object函數實現代碼,那當然是不一樣了.他們是怎么實現的,那我們就不去詳細琢磨了,如果想琢磨的,就可以了解瀏覽器的相關知識了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM