重慶分公司,新征程啟航
為企業提供網站建設、域名注冊、服務器等服務
為企業提供網站建設、域名注冊、服務器等服務
公司主營業務:成都網站設計、網站建設、移動網站開發等業務。幫助企業客戶真正實現互聯網宣傳,提高企業的競爭能力。成都創新互聯公司是一支青春激揚、勤奮敬業、活力青春激揚、勤奮敬業、活力澎湃、和諧高效的團隊。公司秉承以“開放、自由、嚴謹、自律”為核心的企業文化,感謝他們對我們的高要求,感謝他們從不同領域給我們帶來的挑戰,讓我們激情的團隊有機會用頭腦與智慧不斷的給客戶帶來驚喜。成都創新互聯公司推出三亞免費做網站回饋大家。
Function類型
定義函數的三種方式:
1、函數聲明
function sum(num1,num2){ return num1 +num2; }
2、函數表達式
var sum = function(num1,num2){ return num1 + num2; }
3、Function構造函數(不推薦)
//最后一個參數始終都被認作函數體,會導致解析兩次代碼
var sum =new Function("num1","num2","return num1 + num2");
注意:函數名僅僅是指向函數的指針,因此函數名與其他包含對象的指針沒有設么區別
function sum(num1,num2){ return num1 + num2; } alert(sum(10,10)); //20var another = sum; alert(another(10,10)); //20sum = null; alert(another(10,10)); //20sum和another都指向同一個函數,所以講sum設置為null并不影響another
注意:使用不帶圓括號的函數名是訪問函數指針,并不是調用函數
沒有重載
將函數名理解為指針有利于理解為什么沒有重載
function addSomeNumber(num){ return num + 100; }function addSomeNumber(num){ return num + 200; } alert(addSomeNumber(100)); //300
第二個函數將addSomeNumber指向新的函數
函數聲明與函數表達式
解析器在向執行環境中加載數據時,對函數聲明和函數表達式不是一時同仁。解析器會率先讀取函數聲明,并使其在執新行任何代碼之前可用。對于函數表達式,則必須等到執行到它所在的代碼行,才會真正被解析。
alert(sum(10.10)); //20function sum(num1,num2){ return num1 +num2; }
在代碼執行環境之前,解析器會通過一個名為函數聲明提升的過程,讀取并將函數聲明添加到執行環境當中。對代碼求值時,JavaScript引擎在第一遍會聲明函數并將它們放到源代碼樹的頂部
alert(sum(10,10)); sum = (num1,num2){ num1 + num2; }
作為值的函數
可以像傳遞參數一樣把一個函數傳遞給另一個函數,也可以將一個函數作為另一個函數的結果返回。
function callSomeFunction(someFunction,someArugment){ return someFunction(someArugment); }function add10(num){ return num + 10; }var result = callSomeFunction(add10,10); alert(result);//20
可以從一個函數中返回另一個函數
function createComparisonFunction(propertyName){ return function(object1,object2){ var values1 = object1[propertyName]; var values2 = object2[propertyName]; if(values1values2) return 1; else return 0; }; }var data = [{name:"qunzhu",age:21},{name:"huishuai",age:22},{name:"kuolang",age:23}]; data.sort(createComparisonFunction(name)); alert(data[1].name); //huishuai
函數內部屬性
在函數內部,有兩個特殊的對象:arguments和this。
arguments他是一個類數組對象,包含著傳入函數中所有的參數,他有一個callee屬性,該屬性是一個指針,指向擁有這個arguments對象的函數。
function factorial(num){ if(num<=1) return 1; else return num * factorial(num-1); }
函數有一個問題,函數的執行與函數名耦合在了一起
改進:
function factorial(num){ if(num<=1) return 1; else return num * arguments.callee(num-1); }var trueFactorial = factorial; factorial = function(){ return 0; } alert(trueFactorial(5)); //120alert(factorial(5)); //0
this引用的是函數數據以執行的環境對象或者也可以說是this值(當在網頁的全局作用域中調用函數時this對象引用的是window)
window.color = "red";var o = {color:"blue"};function sayColor(){ alert(this.color); } sayColor(); //redo.sayColor = sayColor; o.sayColor(); //blue
ECMAScript5也規范化了另一個函數對象的屬性:caller,這個屬性保存著調用當前函數的函數的引用,如果在全局作用域中調用當前函數,則返回null。
function outer(){ inner(); }function inner(){ alert(inner.caller); } outer();//會彈出警告框,顯示outer()的源代碼
函數屬性和方法
每個函數都有兩個屬性:length和prototype
length屬性表示函數希望接受的命名參數
function sum(num1,num2){ return num1 + num2; } alert(sum.length); //2
對于ECMAScript中的引用類型而言,prototype是保存他們所有實例方法的真正所在,prototype的屬性是不可枚舉的,因此使用for-in無法發現
每個函數都包含兩個非繼承的方法:apply()和call()。這兩個方法的用途都是在指定的作用域中調用函數,實際上等于設置函數體內的this對象的值
function sum(num1,num2){ return num1 + num2; }function callSum1(num1,num2){ return sum.apply(this,arguments); }function callSum2(num1,num2){ return sum.apply(this,[num1,num2]); } alert(callSum1(10,10)); //20alert(callSum2(10,10)); //20
call()方法與apply()方法的作用相同,他們的區別在于接受參數的方式不同,call()方法,第一個參數時this值沒有變化,變化的是其余參數都直接傳遞給函數。換句話說,在使用call()方法時,傳遞給函數的參數必須逐個列舉出來
function sum(num1,num2){ return num1 + num2; }function callSum(num1,num2){ return sum.call(this,num1,num2); } alert(callSum(10,10)); //20
其實call()和apply()真正強大的地方在于能夠擴充函數賴以運行的作用域
window.color = "red"; var o = {color:"blue"}; function sayColor(){ alert(this.color); } sayColor(); //red sayColor.call(this); //red sayColor.call(window); //red sayColor.call(o); //blue
ECMAScript5還定義了一個方法bind()。這個方法會創建一個函數的實例,起this值會綁定到傳給bind()函數的值
window.color = "red";var o = {color:"blue"};function sayColor(){ alert(this.color); }var objectSayColor = sayColor.bind(o); objectSayColor(); //blue
每個函數繼承的toLocaleString()和toString()方法會始終返回函數的代碼。