1. JS函數的概念
函數就是把特定功能的代碼抽取出來词爬,使之成為程序中的一個獨立實體。
2. 函數的作用
正如函數的概念, 我們可以根據需要, 將特定的功能用函數來包裹(封裝)
3. 使用函數的好處
1, 函數可以在同一個程序或其他程序中多次重復使用(通過函數名調用)
2, 使程序變得更簡短而清晰 候学, 提高可讀性
3, 有利于程序維護
4.函數的分類
函數可以分為: 系統(tǒng)函數 內置函數 和 自定義函數
系統(tǒng)函數,內置函數:
是官方提供好的函數翅雏,可以直接使用
如: alert(), isNaN(), console.log() 圈驼,document.write(), Boolean(), Math.pow()等
自定義函數:
函數的簡單定義
定義函數的語法格式:
function 函數名() {
代碼塊;
}
注意:
1, 必須使用function關鍵字, 且為小寫, 函數名可以自己給定
2, 函數名的命名規(guī)則和變量名一致
3, 函數名后必須寫圓括號()
示例: 定義一個函數printOut
function printOut(){
document.write(“Hello World!”);
}
函數的標準定義
定義函數的語法格式:
function 函數名(參數1,參數2望几,……)
{
執(zhí)行語句;
return 返回值;
}
注意: 1, 函數名后圓括號()中的參數數量不定, 也可以沒有; (根據功能需要)
2, return關鍵字的作用是將某個值返回, 如果沒有返回值則默認返回undefined
5.函數的三種寫法
//普通函數
function fn1(n,m) {
return n+m;
}
console.log(fn1(10,20));
//匿名函數(沒有函數名稱)
var fn2=function(n,m) {
return n+m;
}
console.log(fn2(10,20));
//構造函數绩脆,創(chuàng)建函數
var fn3= new Function("a","b","return a+b;")
console.log(fn3(50,40))
6.函數的形參和實參
形參:
形參就是在函數定義時,函數名后面的參數;
函數的形參跟變量是一樣使用,且不能用var修飾
實參:
實參就是調用時橄抹,函數名后面的參數
如: 之前定義的函數sum中: one和two是形參, 2和8是實參
function sum(one, two){
var s = one + two;
return s;
}
sum(2, 8);
7.函數中的arguments數組:
JS中函數不介意傳遞進來多少個參數靴迫,也不在乎傳進來參數是什么數據類型,在調用函數時也未必一定要傳遞指定數量的參數楼誓,原因是 ECMAScript 中的參數在內部是用一個數組(arguments)來表示的玉锌。函數接收到的始終都是這個數組,而不關心數組中包含哪些參數(如果有參數的話)疟羹。
arguments可以判斷參數的個數主守,arguments是個數組。
我們可以使用arguments.length來獲取參數的個數
可以使用arguments[i] 的方式來訪問數組中的第i個參數(i為自己給定的整數下標)
<script>
// arguments
// 1.只能在函數內部出現(xiàn)
// 2.它是偽數組(本質是一個對象)
// 對象多一個length屬性
// 它的作用:1動態(tài)接受實參
// 動態(tài)接受實參
function fn() {
var res=0;
for(var i=0;i<arguments.length;i++) {
res+=arguments[i];
}
return res;
}
var res1=fn(10,20,30);
console.log(res1);
var res2=fn(4,5,6,7);
console.log(res2);
// fn("大白兔","白又白")
//對象不會天生自帶length
//數組會自帶length
</script>
8.DOM的簡單操作
<body>
<input type="text" id="txt">
<button id="btn">提交</button>
</body>
<script>
//想用js操作頁面上元素
//通過id獲取文檔里的元素
var oBtn = document.getElementById("btn");
var oTxt = document.getElementById("txt");
//console.dir 查看對象的詳細信息
//. 的
//console.log(oBtn);
//頁面里面輸入的內容都是字符串型
//1.拿到點擊按鈕榄融,給按鈕綁定點擊事件
oBtn.onclick=function (){
//2.在點擊事件里面参淫,獲取輸入框的值
var res = oTxt.value;
console.log(res);
}
</script>
9.作用域
作用域:
就是起作用的范圍±⒈或者說有效范圍; 這里涉及到另外兩個概念
1.局部變量: 定義在函數內部的變量涎才,這個變量只能在函數內部使用,即作用域范圍只是函數內部力九,另外憔维,形參也是局部變量.
2.全局變量: 全局變量就是定義在函數外部的變量,這個變量在任何函數中都有效畏邢,即作用域范圍是當前文件的任何地方.
注意: 在定義變量時, 如果不寫關鍵字var也是合法的, 且是全局變量, 但是這樣寫不安全,容易在其他地方被更改, 所以我們在函數中寫變量要加上var
<script>
//全局變量和局部變量业扒,同名并同時存在,局部變量優(yōu)先
function fn(n) {
m=10;//全局變量
}
fn(20)
console.log(m);
//console.log(n);
var n=100;
function fn() {
console.log(n); //undefined 變量提升
var n=200;
console.log(n);//200
}
//變量提升是JavaScript 的一種執(zhí)行機制舒萎,大致就是字面意思程储,將聲明的變量提前,
// 但并不是指在編譯時改變語句的順序臂寝,而是將變量 提前 放入內存中章鲤,供后續(xù)操作
// 上面fn的執(zhí)行順序為fn{
// var n;
// console.log(n); //所以n會輸出undefined
// n=200;
// }
fn();
function fn() {
var n=m=200; //var n;所以n是一個局部變量咆贬,而m前面沒有var所以是全局變量
}
fn()
console.log(n);// n is not defined
console.log(m);//200
</script>
10.遞歸調用
遞歸調用: 函數可以自己調用自己,必須要有結束條件,稱為函數的遞歸調用;
重要性:
遞歸的分量败徊,遞歸屬于函數中比較難理解的知識,在應用開發(fā)中掏缎,雖然使用不是很頻繁皱蹦,但是很體現(xiàn)你的功底煤杀,而且,從事IT行業(yè)開發(fā)沪哺,最好要會遞歸沈自,如果說現(xiàn)在可以不要求靈活運用的話,以后到公司中一定要會辜妓,如果面試中有人問你遞歸枯途,說明,他對你要求挺高
10.函數執(zhí)行順序(函數提升)(易錯)
函數提升:
規(guī)則:
1.變量聲明籍滴,函數聲明都會被提升到作用域頂部酪夷;
2.當出現(xiàn)相同名稱函數時,優(yōu)先級:變量聲明<函數聲明<變量賦值
var foo = function(x,y) {
return x-y
}
var foo = function(x,y) {
return x+y
}
var num = foo(1,2)
javaScript編譯器處理后執(zhí)行順序
//variable hositing 變量提升
var foo;//foo#1
var num;
//function declaration hoisting 函數聲明提升
function foo(x,y){ //foo#2
return x + y;
}
//function expression NOT hoisted 函數表達式不會提升
function foo(x,y){ //foo#3
return x - y;
}
num = foo(1,2); 這里使用foo #3
———————————————————————————————————————————————
2021/10/27 更新
聲明式函數 和 賦值型函數
聲明函數與賦值函數的區(qū)別在于: 在 JS 的預編譯期間孽惰,聲明式函數會被先提取出來晚岭,然后才按照順序執(zhí)行 JS代碼。
聲明式函數:
a(); // 'a'
function a() {
console.log('a');
}
賦值型函數:
b(); // Uncaught TypeError: b is not a function
var b = function() {
console.log('b');
}
函數聲明 提前于 賦值函數灰瞻。
console.log(e); // undefined
var e;
console.log(f); //Uncaught ReferenceError: f is not defined
———————————————————————————————————————————————
遞歸調用的方式:
- 首先去找臨界值腥例,即無需計算,獲得的值(一般是返回該值)酝润。
- 找這一次和上一次的關系(一般從后往前找)
- 假設當前函數已經可以使用燎竖,調用自身計算上一次的運行結果,再寫出這次的運行結果
var f = function (x) {
if (x < 2) {
return 1;//當x小于2時要销,函數會返回1构回;不再執(zhí)行else
}
else {
return x * f(x - 1); //遞歸調用
}
}
console.log(f(5)); //得到5的階乘是120
兔子問題
兔子繁殖問題,設有一只新生兔子疏咐,從第四個月開始他們每個月, 月初都生一只兔子,
// 新生的兔子從第四個月月初開始又每個月生一只兔子按此規(guī)律纤掸,并假定兔子沒有死亡,
// n(n<=20)個月月末共有多少只兔子?
function f(n){
if(n == 1 || n == 2){ // 輸入1和2時候浑塞,返回只有一對兔子
return 1;
}
return f(n-1)+f(n-2); //遞歸計算兔子數量
};
f(12); //12個月后一共有144對兔子