摘取:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions
https://msdn.microsoft.com/zh-cn/library/hh968323.aspx
-
大概描述
- 一個(gè)函數(shù)就是一個(gè)可以被外部代碼調(diào)用(或者函數(shù)本身遞歸調(diào)用)的“子程序”
- 函數(shù)可以接受傳入?yún)?shù),也可以返回一個(gè)值
- Function對(duì)象场躯,可以擁有屬性和方法,可以被調(diào)用
- 除了使用new關(guān)鍵字調(diào)用一個(gè)構(gòu)造函數(shù)外,函數(shù)必須使用return語句來指定一個(gè)所要返回的值,否則默認(rèn)返回undefined森瘪。
- 調(diào)用函數(shù)時(shí),傳遞給函數(shù)的值被稱為函數(shù)的實(shí)參(值傳遞)票堵,對(duì)應(yīng)位置的函數(shù)參數(shù)名叫作形參扼睬。
如果實(shí)參是一個(gè)包含原始值(數(shù)字,字符串,布爾值)的變量窗宇,則就算函數(shù)在內(nèi)部改變了對(duì)應(yīng)形參的值措伐,返回后,該實(shí)參變量的值也不會(huì)改變军俊。如果實(shí)參是一個(gè)對(duì)象引用侥加,則對(duì)應(yīng)形參會(huì)和該實(shí)參指向同一個(gè)對(duì)象。假如函數(shù)在內(nèi)部改變了對(duì)應(yīng)形參的值粪躬,返回后担败,實(shí)參指向的對(duì)象的值也會(huì)改變:
example_1:
/*定義函數(shù)myFunc*/
function myFunc(theObject){
//實(shí)參 mycar 和 形參 theObject 指向同一個(gè)對(duì)象。
theObject.brand = "Toyota"
}
/*
*定義變量 mycar
*創(chuàng)建并初始化一個(gè)對(duì)象
*將對(duì)象的引用賦值給變量 mucar
*/
var mycar={
brand:"Honda",
model:"Accord",
year:"1998"
};
/*彈出 'Honda'*/
window.alert(mycar.brand);
/*將對(duì)象引用傳給函數(shù)*/
myFunc(mycar);
/*彈出'Toyota',對(duì)象屬性已被修改*/
console.log(mycar.brand);
-
函數(shù)定義
function fun1() {
//聲明一個(gè)函數(shù)
}
function() {
//聲明一個(gè)匿名函數(shù)
}
var fun2 = function() {
//聲明一個(gè)變量指向一個(gè)匿名的函數(shù)表達(dá)式
}
var fun3 = function fun4() {
//聲明一個(gè)變量指向一個(gè)非匿名的函數(shù)表達(dá)式
}
function fun5() {
return function() {
//返回一個(gè)匿名函數(shù)
} }
* 函數(shù)聲明(函數(shù)語句)
```javascript
function name(params){
statements
}
name
:函數(shù)名
param
:函數(shù)參數(shù)
statements
:組成函數(shù)體的聲明語句
- 函數(shù)表達(dá)式
function [name]([param1[,param2[,...,paramN]]]){
statements
}
name
:函數(shù)名稱镰官,函數(shù)表達(dá)式和函數(shù)聲明的主要區(qū)別是函數(shù)名稱可以被忽略提前,從而創(chuàng)建匿名函數(shù)
paramN
:被傳遞給函數(shù)的一個(gè)參數(shù)名稱
statements
:構(gòu)成函數(shù)體的語句
- 箭頭函數(shù)表達(dá)式(=>)
箭頭函數(shù)表達(dá)式是ECMAScript 6新定義的,箭頭函數(shù)總是匿名的泳唠,并且它擁有詞法作用域的this值
(param1,param2,...,paramN) =>{statement}
(param1,param2,..,paramN) =>{expression}
//equivalent to : => {return expression;}
//如果只有一個(gè)參數(shù)狈网,圓括號(hào)是可以選的:
(singleParam) =>{statements}
singleParam => {statements}
//無參數(shù)的函數(shù)需要使用圓括號(hào):
() =>{statements}
param
:參數(shù)名稱,零參數(shù)需要用()表示笨腥,只有一個(gè)參數(shù)時(shí)則不需要
statements or expression
:多個(gè)聲明statemens需要用大括號(hào)括起來拓哺,而單個(gè)表達(dá)式時(shí)則不需要。表達(dá)式expression也是該函數(shù)的隱式返回值
var a=[
"Hydrogen",
"Helium",
"Lithium",
"Beryllium"
];
var a2=a.map(function(s){return s.length});
//箭頭函數(shù)
var a3=a.map(s=>s.length);
不綁定 this
不綁定 arguments
像方法一樣使用箭頭函數(shù)
不綁定 this
- Function 構(gòu)造函數(shù)
不推薦使用Function構(gòu)造函數(shù)扇雕,因?yàn)樗枰暮瘮?shù)體作為字符串可能會(huì)阻止一些js引擎化拓售,也會(huì)引起其他問題
摘取:http://mp.weixin.qq.com/s/BN0DJBWxUsOp5dGkP
一窥摄、函數(shù)
1.函數(shù)概念:把一些重復(fù)的代碼進(jìn)行封裝镶奉,在使用的時(shí)候直接調(diào)用 函數(shù)只需要定義一次,可以調(diào)用多次
2.函數(shù)定義與調(diào)用
(1)函數(shù)定義
function 函數(shù)名(){ 函數(shù)體; }
函數(shù)在定義的時(shí)候崭放,函數(shù)名后面的小括號(hào)中可以直接寫變量名(變量名前不用寫var)哨苛,不能直接寫值
(2)函數(shù)調(diào)用
函數(shù)名();
3.返回值、形參和實(shí)參
function getSumNumber(num1,num2){
var sum=num1+num2;
return sum;
}
var result=getSumNumber(10,20);
console.log(result);```
(1)形參:函數(shù)在**定義**的時(shí)候币砂,函數(shù)名后面的小括號(hào)中的變量建峭,叫**形參**
(2)實(shí)參:函數(shù)在**調(diào)用**的時(shí)候,函數(shù)名后面的小括號(hào)中的**無論是值還是變量**决摧,叫**實(shí)參**
(3)返回值:函數(shù)在定義的時(shí)候亿蒸,函數(shù)中有 return 值; 叫返回值
(4)如果函數(shù)有return,那么該函數(shù)就有返回值掌桩;但是如果return后面沒有任何的內(nèi)容边锁,該函數(shù)可以說沒有明 確的返回值;如果函數(shù)沒有return波岛,那么該函數(shù)沒有返回值 代碼:
function getSum(num1,num2) {
var sum=num1+num2;
console.log("和為:"+sum);
}
var result=getSum(10,20);//函數(shù)沒有返回值,用變量來接收了
console.log(result);//getSum()沒有return茅坛,所以result undefined
控制臺(tái)結(jié)果:
`和為 30 `
`undefined`
前者是因?yàn)間etSum方法中有輸出,后者因?yàn)闆]有返回值则拷,所以輸出undefined
***
4.函數(shù)4種形式
(1)無參數(shù),無返回值的函數(shù)(函數(shù)中沒有return,括號(hào)里沒有參數(shù))
function getSum() {
var sum=num1+num2;
console.log(sum);
}
(2)有參數(shù),無返回值的函數(shù)(函數(shù)中沒有return,括號(hào)里有參數(shù))
function getSum(num1,num2) {
var sum=num1+num2;
console.log(sum);
}```
(3)無參數(shù),有返回值的函數(shù)(函數(shù)中有return,括號(hào)里沒有參數(shù))
function getSum() {
var sum=num1+num2;
console.log(sum);
return sum;
}
(4)有參數(shù),有返回值的函數(shù)(函數(shù)中有return,括號(hào)里有參數(shù))
function getSum(num1,num2) {
var sum=num1+num2;
console.log(sum);
return sum;
}
5.函數(shù)細(xì)節(jié)及注意——全重點(diǎn)
(1)如果直接輸出函數(shù)的名字,那么顯示的是函數(shù)的代碼
function aa() {
alert("aaa");
return function(){
alert("bbb");
};}
alert(aa);
結(jié)果為控制臺(tái)輸出:
function aa() { alert(“aaa”); return function(){alert(“bbb”);}; } alert(aa);
(2)在函數(shù)調(diào)用執(zhí)行函數(shù)中代碼的時(shí)候,如果遇到了return,那么直接返回,并結(jié)束函數(shù)的調(diào)用贡蓖,return下面的代碼不會(huì)執(zhí)行
(3)當(dāng)一個(gè)變量聲明了,沒有賦值,該變量的結(jié)果是undefined曹鸠;當(dāng)一個(gè)函數(shù)沒有明確的返回值(沒有return或return后面沒有任何內(nèi)容),接收后的結(jié)果就是undefined.
(4)遇到系統(tǒng)的函數(shù),可以按住ctrl加鼠標(biāo)左鍵斥铺,可以查看該函數(shù)
(5)JavaScript中彻桃,實(shí)參和形參個(gè)數(shù)可以不相等,在其它語言中實(shí)參個(gè)數(shù)必須和形參個(gè)數(shù)一致
(6)
unction f1(x,y,z) {
var sum= x+y+z;
console.log(sum);
}
f1(10,20);//結(jié)果為NaN,因?yàn)榈?個(gè)參數(shù)z沒有數(shù)據(jù)類型
f1(10,20,30);//結(jié)果為60
f1(10,20,30,40);//結(jié)果為60
(6)函數(shù)之間可以互相調(diào)用
function f1() {
console.log("哈哈,我又變帥了");
}
function f2() {
console.log("就是這么純潔,就是這么勇敢");
}
function f3() {
f1();
console.log("小楊");
f2();
}
f3();//函數(shù)調(diào)用```
結(jié)果: 哈哈,我又變帥了 小楊 就是這么純潔,就是這么勇敢
(6)js中沒有函數(shù)重載的概念,函數(shù)名一旦重名了,會(huì)調(diào)用最后一個(gè),前面的函數(shù)會(huì)被覆蓋掉晾蜘。(尤其不要和系統(tǒng)的函數(shù)名重名)
重載:方法的簽名相同(函數(shù)返回值叛薯、函數(shù)名稱、函數(shù)參數(shù))笙纤,其它語言(c++耗溜、Java、c#)中有方法的重載省容。
***
二抖拴、函數(shù)的兩種定義方式
1.方式一:函數(shù)的聲明
```javascript
function showTime() {
console.log("今天天氣真好,現(xiàn)在是15點(diǎn)");
}```
2.方式二:函數(shù)的表達(dá)式
```javascript
//函數(shù)表達(dá)式來定義一個(gè)函數(shù)
var sayHi=function () {
console.log("你好");
};
sayHi();```
3.函數(shù):命名函數(shù)和匿名函
(1)定義:
命名函數(shù): 函數(shù)有名字
代碼
function showTime() {
console.log("今天天氣真好,現(xiàn)在是15點(diǎn)");
}
showTime()
匿名函數(shù):函數(shù)沒名字
代碼:
var ff=function () {
console.log("薩瓦迪卡");
};
ff();
(2)定義的同時(shí)直接調(diào)用該函數(shù)
```javascript
(
function () {
console.log("今天吃啥呢?");
}
)()```
等價(jià)于
```javascript
var ff=function () {
console.log("今天吃啥呢?");
};
ff();```
結(jié)果都是控制臺(tái)輸出:
`今天吃啥呢?`
(3)函數(shù)如果是匿名函數(shù),就不會(huì)出現(xiàn)重名的問題
***
三腥椒、JS中的塊級(jí)作用域
1.理論
作用域:變量的使用范圍
塊級(jí)作用域:在其它語言中阿宅,任何一對(duì)**花括號(hào)(大括號(hào){})中**的語句都屬于一個(gè)塊,在這之中定義的所有變量在代碼塊外都是不可見的
JavaScript中沒有塊級(jí)作用域笼蛛,即if,while,do-while,for這些大括號(hào)中定義的變量外部都可以訪問
全局變量:定義在script或者不屬于某個(gè)函數(shù)的變量
全局作用域:全局變量的使用范圍
普通的全局變量和隱式全局變量 :
```javascript
var num=10;//普通全局變量
number=100;//隱式全局變量
局部變量:定義在函數(shù)內(nèi)部的變量,函數(shù)外部不能訪問
局部作用域:局部變量的使用范圍
一旦這個(gè)函數(shù)調(diào)用后,執(zhí)行完畢了,里面的局部變量就會(huì)被釋放(這塊空間中的數(shù)據(jù)被刪除了,空間可以為其他的程序使用)
其它
函數(shù)內(nèi)部可以訪問到該函數(shù)所屬的外部作用域的變量(作用域鏈)
不使用var聲明的變量是全局變量洒放,不推薦使用。
變量退出作用域之后會(huì)銷毀滨砍,全局變量關(guān)閉網(wǎng)頁或?yàn)g覽器才會(huì)銷毀
2.案例
(1)if和while和for循環(huán)中定義的變量往湿,外部可以訪問(沒有塊級(jí)作用域)
for(var i=0;i<10;i++){
var num=100;
}
console.log(i);//10
console.log(num);//100
(2)函數(shù)中定義的變量外部不可以訪問
function f1() {
var num=10;
}
f1();
console.log(num);
控制臺(tái)輸出:報(bào)錯(cuò) Uncaught ReferenceError: num is not defined——num 沒有被定義
四、函數(shù)案例
1.經(jīng)典匿名函數(shù)面試題——alert(aa);惋戏、alert(aa());领追、alert(aa()());
function aa(){
alert("aaa");
return function(){
alert("bbb");
};
}
alert(aa);
alert(aa());
alert(aa()());
(1)alert(aa);的結(jié)果為:
頁面彈出function aa() { alert(“aaa”); return function(){alert(“bbb”);}; }
(2)alert(aa());的結(jié)果為:
先彈出aaa,——執(zhí)行的是aa()里的alert(“aaa”);
再彈出function(){alert(“bbb”);}——執(zhí)行的是alert(aa())响逢,彈出aa()的返回值
(3)alert(aa()()); 結(jié)果為:
先彈出aaa绒窑,——執(zhí)行的是aa()里的alert(“aaa”);
再彈出bbb, ——執(zhí)行的是(function(){alert(“bbb”);}) (),這是定義的同時(shí)直接調(diào)用該函數(shù)
最后彈出undefined——執(zhí)行的是alert();舔亭,因?yàn)閒unction(){alert(“bbb”);}沒有返回值些膨,所以彈出undefined
2.根據(jù)年月日,顯示這天是這一年的第幾天
//1.判斷年份是不是閏年
function isLeapYear(year) {
return year%4==0&&year%100!=0||year%400==0;
}
//2.計(jì)算天數(shù)
function getDays(year,month,day) {
//直接定義一個(gè)變量用來保存日期
var days=day;
//判斷這個(gè)月份是不是一月份
if(month==1){
return days;
}
//計(jì)算總的天數(shù)--先獲取每個(gè)月有多少天5月12日
var months=[31,28,31,30,31,30,31,31,30,31,30,31];
for(var i=0;i<month-1;i++){
//因?yàn)閕從0開始,所以后面為month-1钦铺,小于是因?yàn)?月時(shí)已經(jīng)過去的是2個(gè)月订雾,第3個(gè)月剛開始
days+=months[i];
}
//判斷月份要大于2月份并且是閏年
if(month>2&&isLeapYear(year)){
days++;
}
return days;
}
console.log(getDays(2016,2,15));
3.一個(gè)函數(shù)計(jì)算n個(gè)數(shù)字的和,無論傳入多個(gè)數(shù)字
arguments對(duì)象——可以看成是一個(gè)數(shù)組使用,可以在函數(shù)的內(nèi)部使用,可以在函數(shù)中直接通過arguments.length獲取該函數(shù)在調(diào)用的時(shí)候傳入了幾個(gè)參數(shù)
function getSum() {
//console.log(arguments.length);
//看看傳入幾個(gè)數(shù)字
var sum=0;
for(var i=0;i<arguments.length;i++){
sum+=arguments[i];
//arguments[i]表示輸入的第i+1個(gè)數(shù)字
}
return sum;
}
var result= getSum(10,20,30,40);//函數(shù)調(diào)用
console.log(result);//100
4.求1-num每個(gè)數(shù)字的階乘和
//求某個(gè)數(shù)字的階乘
function getJieCheng(number) {
var ji=1;
for(var i=1;i<=number;i++){
ji*=i;
}
return ji;
}
//求1-某個(gè)數(shù)字的階乘和--函數(shù)做
function getSum(num) {
var sum=0;
//先求num之前包括num每個(gè)數(shù)字的階乘是多少,然后把這些階乘相加
for(var i=1;i<=num;i++){
sum+=getJieCheng(i);//調(diào)用求階乘方法,并求和
}
return sum;
} //1!+2!+3!+4!+5职抡!=153
console.log(getSum(5));//153
5.冒泡排序
//定義函數(shù)
function mySort(arr) {
//控制循環(huán)輪數(shù)
for(var i=0;i<arr.length-1;i++){
//控制每輪循環(huán)幾次
for(var j=0;j<arr.length-1-i;j++){
if(arr[j]>arr[j+1]){
//從小到大葬燎。如果從大到小,arr[j]<arr[j+1]
var temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
return arr;//返回?cái)?shù)組
}
//調(diào)用函數(shù)
var newArr=mySort([2,1,4,7,12,32,23]);
console.log(newArr);
6.反轉(zhuǎn)數(shù)組
function reverseArray(arr) {
//反轉(zhuǎn)---該循環(huán)的作用是交換的次數(shù)
for(var i=0;i<arr.length/2;i++){
var temp=arr[i];
arr[i]=arr[arr.length-1-i];
arr[arr.length-1-i]=temp;
}
return arr;
}
var newArr=reverseArray([10,20,30,40,50]);
console.log(newArr);
7.斐波那契數(shù)列
function getFib(num) {
var sum=0;
var num1=1;
var num2=1;
for(var i=3;i<=num;i++){
sum=num1+num2;
num1=num2;
num2=sum;
}
return sum;
}
console.log(getFib(12));
8.圓的面積—π是已知的
function getS(r) {
return Math.PI*r*r;
}
console.log(getS(5));```
***
9.判斷一個(gè)數(shù)字是不是質(zhì)數(shù)
```javascript
function isZhiShu(num) {
var flag=true;//假設(shè)這個(gè)數(shù)字num是一個(gè)質(zhì)數(shù)
//循環(huán)
for(var i=2;i<num;i++){
if(num%i==0){
flag=false;//不是質(zhì)數(shù)
break;
}
}
return flag;//是質(zhì)數(shù)
}
var result=isZhiShu(8);
if(result){
console.log("是質(zhì)數(shù)");
}else{
console.log("不是質(zhì)數(shù)");
}