深刻理解javascript函數

函數其實是對象,每一個函數都是Function類型的實例,且與其餘類型同樣具備屬性和方法.因爲函數是對象,故函數名即爲指向函數的指針,正是因爲這一點,函數沒有重載,重複定義函數只會後者替換前者.javascript

函數的定義

函數的定義有三種:java

  • 函數聲明web

function sum(num1,num2){
return num1+num2;
}
  • 函數表達式數組

var sum=function(sum1,sum2){
 return sum1+sum2;
}
  • 使用Function構造函數(不推薦使用)app

var sum=new Function('num1','num2','return num1 + num2;');

注:函數聲明和函數表達式的惟一區別是函數聲明會提早.意即函數調用在函數聲明以前能夠正常運行.函數

做爲值的函數

前面提到函數是對象,因此函數也能夠做爲參數值或返回值.性能

//做爲參數
function callSomeFunction(someFunction,someArgument){
reuturn someFunction(someArgument);
}

function add10(num){
return num+10;
}

var result=callSomeFunction(add10,10);
alert(result); //20

//做爲返回值
function createCompareFunction(propertyName){
 return function(object1,object2){
 var value1 = object1[propertyName];
 var value2 = object2[propertyName];
   if(value1 < value2){
   return -1;
   }
   else if(value1 > value2){
   return 1;
   }
   else{
   return 0;
   }
 }
}

函數內部屬性

在函數內部有兩個特殊對象:arguments this
arguments是一個類數組對象,包含傳入函數中的全部參數(這是其主要用途),除此以外,其還有一個callee的屬性,該屬性是一個指針,指向當前函數對象.
this引用的是函數據以執行的環境對象.在調用函數以前,this的值是不肯定的,當在全局對象中調用函數時,this引用的是全局對象window,當把函數賦值給某對象時,this指的是此對象.this

window.color = "red";
function sayColor(){
alert(color);
}
sayColor(); //red

var o={color:'blue'};
o.sayColor = sayColor;
o.sayColor();//blue

函數的屬性和方法

  1. 屬性
    length:函數但願接收的命名參數的個數.
    prototype:這是一個很是回味無窮的屬性,它保存着函數的實例方法,意即到經過函數實例化獲得的對象能夠訪問prototype中的方法.此屬性在自定義引用類型和實現繼承頗有用處.prototype

  2. 方法
    apply call這兩個方法是函數的非繼承方法.用途都是設置函數體內this對象的值.指針

apply接收兩個參數,第一個是運行函數的做用域,通俗的說就是將這個參數做爲this指向的值.第二個參數是數組做爲執行函數的參數.

function sum(num1,num2){
return num1+num2;
}
function callSum(num1,num2){
return sum.apply(this,arguments);
}
alert(callSum(10,10)); //20

call接收的第一個參數也是運行函數的做用域,後面的參數也是傳遞給執行函數的參數,與apply不一樣的是,後面的參數並不是數組,而是逐個列舉出來的.

function sum(sum1,sum2){
return sum1+sum2;
}
function callSum(num1,num2){
return sum.call(this,num1,num2);
}
alert(callSum(10,10)); //20

構造函數

ECMAScript中的構造函數能夠建立特定類型的對象.內置的構造函數(例如Array Object)會自動出如今執行環境中.構造函數的首字母應該以大寫字母開頭,從而區分非構造函數.
要建立新的實例,必須使用new操做符,穿件新的實例會經歷如下四個步驟:

  1. 建立一個新對象

  2. 將構造函數的做用域賦值給新對象(所以this指向這個新對象);

  3. 指向構造函數中的代碼.

  4. 返回新對象

function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
alert(this.name);
};
}

var person=new Person('Mr pu',24,'web developer');

構造函數與普通函數的區別在於構造函數在實例化時加了new關鍵字.其它地方徹底同樣.

重要提示 在經過構造函數實例化對象時,請勿把方法放在構造函數中,由於每一個函數(在這裏指方法方法)都是對象,每次實例化一個對象時這個對象中會保存每一構造函數中的方法,這是很影響性能的.解決辦法是把這些方法放在prototype屬性中.

相關文章
相關標籤/搜索