函數
如果有一段代碼要反覆執行
那麼我們可以用大括號 包起來 起個名字 用來反覆調用
這就是函數
所謂函數就是一段代碼可以反覆執行 只要調用函數 就可以反覆執行重複的代碼
函數定義的格式:
function 函數名(參數(形參)){
函數體代碼(要被反覆執行的代碼)
}
調用函數
函數名(實參);
function show(){
console.log("請不要秀");
}
show();
因爲函數運行過程中可能需要外部(函數調用者)傳進來指定的數據
所以函數需要參數
格式:
//形式參數
function 函數名(參數1,參數2,參數3,...參數n){
}
函數調用: 傳入實際參數
要和形式參數 格式一樣
函數名(實參1,實參2,實參3,...實參n)
function plus(a){ //形參
console.log(a+10);
}
plus(55) //實參
plus(108)
形參和實參的數量不一致時的處理:
形參大於實參時(需要三個參數 我卻傳了2個 少傳了):
多於的形參 值爲undefined
形參小於實參(需要三個參數 我卻傳了4個 多傳了):
多於的實參不予理會
形參和實參數量相等:
正常使用
function show(a,b,c) {
console.log(a,b,c);
}
// show(5,6)
show(5,6,7,8)
在js中沒有函數重載 所以 函數不要重名
一旦重名 則後來的覆蓋之前的
function show() {
console.log("我是第一個show函數");
}
function show(a) {
console.log("我是第二個show函數(帶一個參數)");
}
show();
有些時候 函數運行需要 返回給外部一個結果
例如:
計算的函數,計算完 把結果返回給外部使用
這樣比直接在函數內部把結果打印要好
因爲實際開發中 打印語句只是用來調試程序的
總不能讓用戶去看控制檯吧
如何返回一個結果給給外部:
在函數的最後一行 通過 return 結果; 返回一個結果給外部使用
調用者接收返回值
var 變量=函數名(參數); 調用函數並接收到返回值 存入變量中
return 都可以返回哪些類型呢?
所有類型都可以返回
/* function plus(a,b) {
return a+b;
}
var result=plus(55,66);
console.log(result);
console.log(result*10);*/
/* function jian(a,b) {
return a-b;
}
console.log(jian(10,8));*/
函數的返回值幾個注意點:
1.函數裏面如果沒有return 那麼函數默認返回undefined
2.return 執行了 那麼return後面的值 就是返回值
3.有return語句 但是return後面沒有跟任何結果
那麼返回值也是undefined
意義:單純的爲了停止函數(return 表示一個函數結束)
4.return 後面不能寫任何代碼 寫了 也無法執行
break和continue一樣的效果
5.實際開發中 函數的返回值要保持一致的 類型一致 不要隨意切換類型
或者乾脆別反悔 否則 會導致程序混亂
函數創建有兩種方式:
1.函數模式
function 函數名(){}
2.變量模式創建
var 函數名=function(){}
function(){} --->匿名函數
function show() {
}
var demo=function(a,b){
console.log("我是demo函數");
return a+b;
};
var result=demo(9,15);
console.log(result);
函數名,函數體和函數加載
直接打印函數名,把函數代碼整個以字符串打印出來
函數名就代表整個函數
執行函數,就是等於執行函數的代碼並且返回一個返回值
函數名() 就是調用函數,執行函數裏面的代碼 並得到一個返回值
調用函數中如果包含函數,那麼會先執行裏面,再執行外面
先執行內部函數 取得返回值 然後再拿着返回值 執行外部函數
也就是內部函數的返回值 就是外部函數的參數
/*function show() {
console.log("我是一個show函數");
}
console.log(show);
console.log(show());//調用函數並取得返回值 返回undefined*/
作爲作用域:
作用的域 作用:生效的意思 域:範圍
變量的作用域 就是變量的生效範圍
在js中作用域分爲兩種:
全局作用域:
在函數外(不在任何一個函數內) script標籤內聲明的變量
就是全局變量 全局作用域下的變量
在變量創建後的任意位置都可以使用
局部作用域
在函數內聲明的變量就是局部變量 只能在當前函數內使用
函數外再也無法使用
生命週期:
全局變量:
頁面加載時 全局變量被創建
頁面關閉時 銷燬
生命週期比較長 容易空佔內存
局部變量:
方法調用時創建 方法調用完畢銷燬
生命週期比較短 推薦使用
/*var a=10;
/!*console.log(a);
function show() {
console.log(a);
}
show();*!/
function demo() {
var num=99;
console.log(num);
}
demo();
console.log(num);//num is not defined 報錯*/
隱式全局變量:
不適用var創建的變量
不推薦使用(就是不要使用!!!!!!!!!!!!)
demo();//函數提升到當前作用域第一行 所以當前作用域任意位置都可以調用
/*
在js代碼開始一行一行往下運行之前
存在一個預解析階段
相當於大概看一眼 下面的代碼 都聲明瞭 哪些變量和函數
也就是 在預解析階段 js程序會首先把 用var 聲明的變量
和用function創建的函數 進行一個提升
變量提升:
在預解析階段 用var聲明的變量可以被提升到當前作用域!!!的第一行
全局變量被提升到全局第一行
局部變量 被提升到局部第一行
變量只提升變量名 不提升變量值
函數提升
在預解析階段 用function創建的函數會被整個提升到當前作用域第一行
函數提升 是提升整個函數
在當前作用域任意位置都可以調用
/*
//全局變量提升
console.log(a);//undefined
var a=10;
//模擬提升後的代碼 var a;
console.log(a);
a=10;*/
// 局部變量的提升
/*function show() {
console.log(num);
var num=10;
}
show();
//提升後的代碼
function show() {
var num; //局部變量提升到局部第一行
console.log(num);
num=10;
}*/
小知識點
函數不調用就不執行
函數名就等於整個函數
加載函數的時候,只加載函數名,不加載函數體
函數不論是提升還是加載 只加載函數名 不執行不加載函數裏面的代碼
參數相當於局部變量
函數的參數 只能在當前函數中使用 就是一個局部變量
就近原則使用變量
如果函數內部調用變量時 函數內部有這個變量了 那麼就不去外部找
兩個平級的函數中的變量不會互相影響(可以使用相同的形參名)
兩個函數之間 內部的局部變量 完全不影響
函數的高級
<script>
//匿名函數----瞭解
/* var show=function(){} //匿名函數用作函數創建
function qq() {
return function(){}; //匿名函數可以作爲返回值(js高級的閉包去講)
}
function ww(fn) {
}
ww(function(){}); //匿名函數作爲參數->回調函數(一會講)
//後面講定時器
setTimeout(function () {
//頁面加載完畢 5秒後 執行這裏面的代碼
},5000)*/
//函數也是一種數據類型---->瞭解
/* function show() {
}
console.log(typeof show);//function*/
//遞歸函數--->瞭解
//所謂遞歸函數 就是函數自己調用自己
/*function show() {
console.log("我是遞歸函數");
show();
}
show();*/
/*
遞歸函數 最重要的是 結束條件
*/
var i=0;
function show() {
i++;
console.log("我是遞歸函數");
if(i<10){//結束條件
show();
}
}
show();
</script>
函數的高級之回調函數
<script>
/*
所謂回調函數:
就是回來調用的函數 就是函數作爲參數傳入其他函數 讓其他函數來調用
*/
/*function show(fn) {
console.log("我是show方法");
// 調用參數的函數
fn();
}
/!*show(function(){
console.log("我是回調,居然被調用了");
})*!/
show(function () {
})*/
//回調函數
function show(fn) {
console.log("我是show方法");
fn(9,8);//函數調用
}
show(function (a,b) {
console.log("我是回調函數",a,b);
})
</script>