[javascript基礎]函數

來源:互聯網
上載者:User

前言 我在上一篇【javascript基礎】基本概念中介紹了javascript的一些基本概念,多謝大家的閱讀和意見,自己寫的東西可以被大家閱讀,真心高興,剛開始發布的時候我一直盯著閱讀人數,雖然知道大家可能就是點開一下而已,但是還是給我一些繼續寫下去的信心。那今天寫一些關於javascript函數的一些知識,協助大家熟悉或者複習一些函數的基本知識。 PS:最近jQuery源碼交流群( 239147101)加了不少熱新人,希望大家還是以學習為主,盡量少灌水,給大家一個好的提升自己的環境。 函數 函數在任何一種程式設計語言中都是一個很重要的結構或者組成部分,編程中的複雜結構和功能都會有函數的參與。javascript中的函數是一個對象,函數對象時Function類型的執行個體,由於Function類型是一個參考型別,那麼函數可以擁有自己的方法和屬性,同時也因為函數是一個對象,那麼函數名是一個指向函數對象的指標,可以被賦值。下面詳細介紹函數的各個部分。 建立函數 函數的建立有三種方式,分別為使用Function的建構函式、函式宣告、函數運算式,下面分別介紹這三種方法。 Function建構函式 這種方式是直接new出來一個Function 執行個體,通過使用Function的建構函式進行建立函數。Function建構函式可以接收任意多個參數,但是最後一個參數會被認為是函數體,前面的所以參數被當做被建立出來的函數的參數。 var test = new Function("a","b","return a + b");//參數a和b,函數體return a + bconsole.log(test(1,2));//3我們可以看出比較的麻煩,並且《javascript進階程式設計》也不推薦我們使用這種方式,主要是因為瀏覽器要解析常規的javascript代碼之外,還要解析傳入的參數字串,這個類似eval()的解釋,影響效能。 函數運算式 這種方式是建立的常見方式之一,具體請看 var test = function(a,b){  return a + b;  }console.log(test(1,2));上面的代碼就是建立一個函數,使用test()進行調用。其實,上面的代碼是先建立了一個匿名的函數,之後把這個匿名的函數賦值給test變數。每個函數有一個name屬性,這個屬性不是ECMA標準的一部分,但是許多地方可以使用它。我們可以給上面的函數起一個名字,具體下面代碼 複製代碼//函數的名字newNamevar test = function newName(a,b){  return a + b;  }console.log(test.name);//newName //匿名函數var nTest = function (a,b){  return a + b;  }console.log(nTest.name);//undefined複製代碼這個屬性在後面詳細解釋吧。 函式宣告 這種方式和C語言中的很類似,這種是最常見的一種建立函數的方法。是通過關鍵字function直接聲明,請看 function test(a,b){  return a + b;  }console.log(test(1,2));//3console.log(test.name);//test區別 以上介紹了三個建立函數的方式,現在介紹三種的區別,確切的說是後兩種的區別,因為Function不推薦使用,效能是一大原因。區別就是使用函式宣告這種方式會使函數的聲明提前,類似前面我們提到的變數申明的提前。也就是說,使用函數申明方式,我們可以將函數的聲明放在調用函數代碼的後面,因為解析器會在代碼執行之前將函數的聲明提升,提到原始碼樹的頂部,而函數運算式方式則會報錯,具體請看 複製代碼//調用函數console.log(test(1,2));//3//建立函數(函數申明方式)function test(a,b){  return a + b;  }//上面的函數相等於//建立函數(函數申明方式)//function test(a,b){//  return a + b;  //}//console.log(test(1,2));//3 //調用函數console.log(ntest(1,2));//TypeError: undefined is not a function//建立函數(函數運算式方式)var ntest = function (a,b){  return a + b;  }複製代碼not重載 javascript語言不像java那些語言有函數重載這一概念,其實函數名就是一個指標,指向一個Function執行個體的地址,當然只能指向一個函數,當然沒有重載的概念了,只有覆蓋,後面定義的函數覆蓋前面定義的函數,具體請看 複製代碼function test(a,b){  return a + b;  }//下面的函數覆蓋上面的function test(a,b){  return a + b + 100;  } console.log(test(0,0));//100複製代碼也就是說如果一個同名的函數運算式和函數申明的函數在一起,無論位置是怎麼樣的,最後的函數就會是用函數運算式建立的函數,因為函數申明會提升到頂部嘛,看看下面的代碼 複製代碼var test = function (a,b){  return a + b -100;} function test(a,b){//會被下面的函數覆蓋  return a + b;  } function test(a,b){//會被函數運算式覆蓋  return a + b + 100;  } console.log(test(0,0));//-100複製代碼內部屬性 函數的內部有兩個重要的對象:arguments和this。 arguments arguments是一個類似組對象,包含所以傳入函數的所有參數, 寫程式或者面試中常問的就是如何將arguments轉化完成一個數組,請看 Array.prototype.slice.call(arguments);Array.prototype.slice.call(arguments,0);Array.prototype.slice.call(arguments,0,arguments.length);Array.apply(this, arguments); //沒用過Array.apply(null, arguments); //沒用過arguments有一個length屬性,表示函數傳入參數的個數,還有一個callee屬性,這是一個指標,指向擁有這個arguments的函數,這個主要是在函數內部調用自己時使用,也就是遞迴時使用。看個例子就明白了 複製代碼function test(count){ console.log("參數:"+arguments[0]+"個數:"+arguments.length);    if(count <=  0){      console.log("遞迴"+count+" 結束了");  }else{        console.log("遞迴"+count);        arguments.callee(--count);//調用自己     }  }test(3);/*參數:3個數:1遞迴3參數:2個數:1遞迴2參數:1個數:1遞迴1參數:0個數:1遞迴0 結束了*/複製代碼this  javascript中的this和java中的this差不多,this引用的是函數的執行環境,就是this在不同的執行環境中引用的是不同的對象,執行環境這裡還沒有說到,以後會詳細介紹,這裡的this也是簡單的介紹一下,我以後會整理一些面試題,協助大家理解。看例子吧, 複製代碼//全域變數var color = "red";//相當於window.color = "red"//定義一個對象var obj = {color : "blue"};function pop(color){  alert(this.color);}pop();//相當於window.pop();輸入"red"//obj對象增加一個方法,將pop賦值給它obj.pop = pop;obj.pop(); //輸出"blue"複製代碼解釋一下,this這個對象是在函數執行時才綁定的,可以說是一個動態。pop函數是定義在window下的一個函數,也就是全域範圍的一個函數,當直接執行pop函數時,就是在全域範圍下調用pop時。this引用的是window,this.color就是window.color,輸出red。當我們把pop這個函數賦值給obj這個對象並且調用pop的時候,this引用的就是obj這個對象,this.color 就是obj.color,輸出blue。 函數屬性和方法 這裡說一下函數的屬性和方法,包括length,name,prototype,apply,call這幾個。 length 這個屬性比較簡單,就是表示定義函數時定義的參數的個數,要和arguments.length區分開,arguments.length表示實際輸入的參數個數,看例子 複製代碼function test(a,b){  console.log("輸入的參數個數:"+arguments.length);  console.log("定義的參數個數:"+test.length);}test();//0,2test(1);//1,2test(1,2)//2,2test(1,2,3)//3,2//函數的內部我們可以通過arguments[i],取得輸入的參數,假如定義一個參數,輸入兩個參數,那怎麼取得第二個參數呢function testA(c){  console.log("輸入的參數個數:"+arguments.length);  console.log("定義的參數個數:"+test.length);  console.log("第二個參數:"+arguments[1]);}testA(1,100);2,2,100//這裡可以遍曆取得所有的參數,不講了複製代碼name 這個屬性在前面提到了一點,這個就是函數的名字,我們在建立函數的時候說了這個屬性,這個屬性不是標準屬性,但是很多地方就使用這個屬性,主要也是在遞迴調用上使用。name屬性是唯讀屬性,不能修改它的值。直接看例子 複製代碼//修改name屬性function test(){  console.log(test.name);  //修改name屬性  test.name = "newName";  console.log(test.name);}test();//test,test//函數內部使用name屬性,遞迴調用function testD(count){ console.log("參數:"+arguments[0]+"個數:"+arguments.length);    if(count <=  0){      console.log("遞迴"+count+" 結束了");  }else{        console.log("遞迴"+count);        testD(--count);//調用自己     }  }testD(3);/*參數:3個數:1遞迴3參數:2個數:1 遞迴2參數:1個數:1遞迴1參數:0個數:1 遞迴0 結束了 */複製代碼name屬性的使用和arguments.callee()的效果是一樣的,只不過arguments.callee()更方便些,當函數名字更改時程式不用更改。 prototype 函數的prototype屬性是一個很重要的屬性,特別是在自訂參考型別和實現繼承時。我們現在這簡單的介紹一下它,因為這個屬性足以單獨寫一篇文章。我們可以認為prototype是一個模板,在new 一個對象時候會參照這個模板,將模板裡的屬性和方法複製給對象,當然你不定義這個模板,這個模板不存在方法和屬性。簡單例子 複製代碼function People(name){  this.name =  name;}//prototype中的屬性People.prototype.home = "jilin";var hainan = new People("hainan");console.log(hainan.home);//jilin複製代碼先簡單介紹到這,後面單獨詳細說。 call和apply 這兩個方法作用是一樣的,就是改變this範圍的值,在特定的範圍中調用自己,也就是設定this的指向,不同點在於參數接收方式不同。apply方法需要兩個參數,第一個是指定的範圍,就是要把this指向的對象,第二個是參數數組,函數調用需要的參數,這個參數數組也可以是arguments這個偽數組。call的第一個參數也是給this綁定的值,其他的參數個數不定,其他的參數就是函數調用需要的參數,和apply不同,你要一個一個的都列舉出來。看例子 複製代碼function sum(a,b){  return a + b;      }//arguments參數function callSum1(a,b){  return sum.apply(this,arguments);  }//數組參數function callSum2(a,b){  return sum.apply(this,[a,b]);  }//列舉所有參數function callSum3(a,b){  return sum.call(this,a,b);  }console.log(callSum1(1,2));console.log(callSum2(1,2));console.log(callSum3(1,2));複製代碼上面是傳遞參數的例子,再看看改變this指向的例子 複製代碼//全域變數var color = "red";//相當於window.color = "red"//定義一個對象var obj = {color : "blue"};function pop(color){  alert(this.color);}pop();//相當於window.pop();輸入"red"pop.call(this);//redpop.call(obj);//blue複製代碼解釋一下,pop.call(this)這句代碼改變了this的指向,因為是在全域中調用的函數,this指向window,輸出window.color。pop.call(obj)這句代碼將this指向了obj,所以輸出obj.color。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.