感激相遇,你好,我是阿ken🦓
?
著作權宣告:本文為CSDN博主「請叫我阿ken」的原創文章,遵循CC 4.0 BY-SA著作權協議,轉載請附上原文出處鏈接及本宣告,
另外,博文中某些圖片或內容可能出自網路,如有侵權或問題,請及時私信我
有學妹想以后做前端,就會問到 JavaScript怎么學的問題,在多次百般盤問下,阿ken🦁 決定貢獻出自己之前學習 JavaScript時的筆記,
?
安全感這個東西對于大多數人而言
是靠很多次堅持不懈去努力爭取的
不要因為沒怎么努力過
到頭來連一件值得回憶的事情都沒有
這不是為了向別人證明自己了不起
這只不過是把本該屬于自己的東西奪回來
🧡💛💚💙💜🤎🖤🤍
傳送門biu~???
- 📚4.1_初識函式
- 📙4.1.1_函式的使用
- 📗4.1.2_函式的引數
- 📘4.1.3_函式的回傳值
- 📚4.2_函式回傳值案例
- 📙4.2.1_利用函式求任意兩個數的最大值
- 📗4.2.2_利用函式求任意一個陣列中的最大值
- 📘4.2.3_利用 return 提前終止函式
- 📒4.2.4_利用 return 回傳陣列
- 📚4.3_函式綜合案例
- 📙4.3.1_利用函式求所有引數中的最大值
- 📗4.3.2_利用函式反轉陣列元素順序
- 📘4.3.3_利用函式判斷閏年
- 📒4.3.4_獲取指定年份的2月份的天數
- 📚4.4_函式進階
- 📙4.4.1_函式運算式
- 📗4.4.2_回呼函式
- 📘4.4.3_遞回呼叫
- 📚4.5_作用域
- 📙4.5.1_作用域的分類
- 📗4.5.2_全域變數和區域變數
- 📘4.5.3_作用域鏈
- 📚4.6_閉包函式
- 📙4.6.1_什么是閉包函式
- 📗4.6.2_閉包函式的實作
- 📚4.7_預決議
- 📙4.7.1_預決議_var 變數宣告
- 📗4.7.2_預決議_function函式宣告
📚4.1_初識函式
📙4.1.1_函式的使用
function 函式名() {
//函式體代碼
}
function 是宣告函式的關鍵字,必須全部使用小寫字母,
當函式宣告后,里面的代碼不會執行,只有呼叫函式的時候才會執行,
呼叫函式的語法為“函式名( )”,
案例:
//宣告函式
function sayHello() {
console.log ('Hello');
}
//呼叫函式
sayHello();

📗4.1.2_函式的引數
函式的引數分為形參和實參,
在宣告函式時,可以在函式名稱后面的小括號中添加一些引數,這些引數被稱為形參,
當函式呼叫的時候,同樣也需要傳遞相應的引數,這些引數稱為實參,
函式的形參是形式上的引數,因為當函式宣告的時候,這個函式還沒有被呼叫,這些引數具體會傳過來什么樣的值是不確定的,而實參是實際上的引數,在函式被呼叫的時候,它的值就被確定下來了,
案例:
function 函式名 (形參1, 形參2, ...) {
// 函式體代碼
}
函式名 (實參1, 實參2, ...);
JavaScript 函式引數的使用非常靈活,它允許函式的形參和實參個數不同,當實引數量多于形引數量時,函式可以正常執行,多余的實參由于沒有形參接收,會被忽略,除非用其他方式(例如后面學到的 arguments )才能獲得多余的實參,當實引數量小于形引數量時,多出來的形參類似一個已宣告未賦值的變數,其值為 undefined,
function getSum (num1, num2) {
console.log (num1, num2);
}
getSum (1, 2, 3); // 實引數量大于形引數量,輸出結果為 1,2
getSum (1); // 實引數量小于形引數量,輸出結果為 1,undefined

📘4.1.3_函式的回傳值
例如,一個人去餐廳吃飯,我們將餐廳的廚師看成一個函式,顧客通過函式的引數來告訴廚師要做什么菜,當廚師將飯菜做好以后,這個飯菜最終應該是傳給顧客,但我們在前面撰寫的函式都是直接將結果輸出,這就像廚師自己把飯菜吃了,沒有將函式的執行結果回傳給呼叫者,
格式:
function 函式名() {
return 要回傳的值; //利用 return 回傳一個值給呼叫者
}
案例:
function getResult() {
return 666;
}
// 通過變數接識訓傳值
var result = getResult();
console.log (result); // 輸出結果:666
// 直接將函式的回傳值輸出
console.log ( getResult() );// 輸出結果:666
console.log (getResult);// 輸出結果:輸出函式(見下圖)

反例:
function getResult() {
console.log (1);
// 該函式沒有return
}
getResult(); // 輸出結果: 1
console.log ( getResult() ); // 輸出結果: 1 undefined

📚4.2_函式回傳值案例
📙4.2.1_利用函式求任意兩個數的最大值
function getMax (num1, num2) {
if (num1 > num2) {
return num1;
} else {
return num2;
}
}
console.log ( getMax(1, 3) ); // 輸出結果: 3

或者
function getMax (num1, num2) {
return num1 > num2 ? num1 : num2;
}
console.log ( getMax(1, 3) ); // 輸出結果:3

📗4.2.2_利用函式求任意一個陣列中的最大值
回顧一下如何創建陣列:
【熬夜猛肝萬字博文】學妹問我怎么入門 Javascript,百般盤問下我終于決定貢獻出自己的 JavaScript入門筆記(三)
function getArrMax(arr) {
var max = arr[0];
for(var i = 1; i <= arr.length; i++) {
if(arr[i] > max) {
max = arr[i];
}
}
return max;
}
var arr = getArrMax([5, 2, 99, 101, 67, 77]);
console.log(arr); // 輸出結果: 101

或者
function getArrMax(arr){
var max = arr[0];
for(var i = 1; i <= arr.length-1; i++) {
if(arr[i] > max){
max = arr[i];
}
}
return max;
}
console.log( getArrMax( [5, 2, 99, 101, 67, 77]) );
// 輸出結果:101

📘4.2.3_利用 return 提前終止函式
return 陳述句之后的代碼不會被執行,
例如:在 getMax() 函式中判斷兩個引數是否都是數字型,只要其中一個不是數字型,則提前回傳 NaN,
function getMax(num1,num2){
if(typeof num1 != 'number' || typeof num2 != 'number'){
return NaN;
}
return num1 > num2 ? num1 : num2;
}
console.log( getMax(1, '3') ); // 輸出結果:NaN

NaN( Not a Number,非數),是計算機科學中數值資料型別的一類值,表示未定義或不可表示的值,
null(空型)、undefined(未定義型)、number(數字型) 為基本資料型別,
📒4.2.4_利用 return 回傳陣列
在函式中使用 return 時,應注意 return 只能回傳一個值,即使使用多個逗號隔開多個值,也只有最后一個值被回傳,
function fn(num1, num2){
return num1, num2;
}
console.log( fn(1, 2) ); // 輸出結果:2

在開發中,當需要回傳多個值的時候,可以用陣列來實作,也就是將要回傳的多個值寫在陣列中,作為一個整體來回傳,
function getResult(num1, num2){
return [num1 + num2, num1 - num2, num1 * num2, num1 / num2];
}
console.log( getResult(1,2) ); // 輸出結果: (4)[ 3, -1, 2, 0.5 ]

📚4.3_函式綜合案例
📙4.3.1_利用函式求所有引數中的最大值
function getMax(){
var max = arguments[0];
for(var i = 1; i < arguments.length; i++) {
if (arguments[i] > max) {
max = arguments[i];
}
}
return max;
}
console.log( getMax(1,2,3) );// 輸出結果:3
console.log( getMax(1,2,3,4,5) );// 輸出結果:5
console.log( getMax(11,2,34,666,5,100) );// 輸出結果:666
📗4.3.2_利用函式反轉陣列元素順序
function reverse(arr){
var newArr = [];
for(var i = arr.length - 1; i >= 0; i--){
newArr[newArr.length] = arr[i];
}
return newArr;
}
var arr1 = reverse( [1, 3, 4, 6, 9] );
console.log(arr1);// 輸出結果:(5)[9,6,4,3,1]
📘4.3.3_利用函式判斷閏年
function isLeapYear(year){
var flag = false;
if(year % 4 == 0 && year % 100 != 0 || year % 400 == 0){
flag = true;
}
return flag;
}
console.log( isLeapYear(2020) ? '2020是閏年' : '2020不是閏年' );// 2020是閏年
console.log( isLeapYear(2021) ? '2021是閏年' : '2021不是閏年' );// 2021不是閏年
📒4.3.4_獲取指定年份的2月份的天數
//該題目答案要加上4.3.3的代碼
function fn(){
var year = prompt('請輸入年份');
if ( isLeapYear(year) ){
alert('當前月份是閏年,2月份有29天')
}else{
alert('當前月份是平年,2月份有28天')
}
}
function isLeapYear(year){
var flag = false;
if(year % 4 == 0 && year % 100 != 0 || year % 400 == 0){
flag = true;
}
return flag;
}
fn();
📚4.4_函式進階
📙4.4.1_函式運算式
函式運算式是將宣告的函式賦值給一個變數,通過變數完成函式的呼叫和引數的傳遞,
//函式宣告
function funcName() {
// 函式體
}
var sum = function (num1, num2) {
// 函式運算式
return num1 + num2;
};
console.log ( sum(1,2) ); // 3
函式運算式與函式宣告的定義方式幾乎相同,不同的是函式運算式的定義必須在呼叫前,而函式宣告的方式則不限制宣告與呼叫的順序,由于 sum 是一個變數名,給這個變數賦值的函式沒有函式名,所以這個函式也叫匿名函式,
將匿名函式賦值給了變數 sum 后,變數 sum 就能像函式一樣呼叫,
📗4.4.2_回呼函式
專案開發中,若想要函式體中某部分功能由呼叫者決定,此時可以使用回呼函式,所謂回呼函式指的就是一個函式A作為引數傳遞給一個函式B,然后在B的函式體內呼叫函式A,此時,我們稱函式A為回呼函式,其中,匿名函式常用作函式的引數傳遞,實作回呼函式,
function cal(num1,num2,fn){
return fn(num1,num2);
}
console.log( cal(45,55,function(a,b){
return a+b; })
);
console.log(cal(10,20,function(a,b){
return a*b; })
);

回呼函式和遞回呼叫好好理解一下
📘4.4.3_遞回呼叫
遞回呼叫是函式嵌套呼叫中一種特殊的呼叫,
它指的是一個函式在其他函式體內呼叫自身的程序,這種函式成為遞回函式,
遞回函式和回呼函式的區別,這是你需要思考的
需要注意的是,遞回函式只可在特定的情況下使用,如計算階乘,
function factorial(n){ //定義回呼函式
if( n == 1 ){
return 1;
}
return n * factorial(n - 1);
}
var n = prompt('求n的階乘\n n是大于等于1的正整數,如2表示求2!,');
n = parseInt(n);
if(isNaN(n)){
console.log('輸入的n值不合法');
}else{
console.log(n + '的階乘為:'+factorial(n));
}
自己想辦法搞一搞,對于剛學小白來說,有點難
📚4.5_作用域
📙4.5.1_作用域的分類
變數需要先定義后使用,但宣告變數后并不是就可以在任意位置使用該變數,
function info() {
var age = 18; //此處age為區域變數
}
info();
console.log (age);
//報錯,提示age is not defined(age未定義)
//該處只能呼叫全域變數
從上述代碼中可以看出,變數需要在它的作用范圍內才可以被使用,這個作用范圍稱為變數的作用域,JavaScript 根據作用域使用范圍的不同,將其劃分為全域作用域、函式作用域和塊級作用域(ES 6提供的)
- ① 全域變數: 不在任何函式內宣告的變數都稱為全域變數, 它在同一個頁面檔案中的所有腳本內都可以使用,
- ② 區域變數: 在函式體內利用 var 關鍵字定義的變數稱為區域變數, 它僅在該函式體內有效,
- ③ 塊級變數: ES 6提供的let 關鍵字宣告的變數稱為塊級變數, 它僅在該函式體內有效,(理解即可)
📗4.5.2_全域變數和區域變數
//全域作用域
var num = 10; //全域變數
function fn() {
//區域作用域
var num = 20; //區域變數
console.log (num); //輸出區域變數num的值,輸出結果:20
}
fn();
console.log (num);
//輸出全域變數10的值,輸出結果:10
在上述代碼中,全域變數num和區域變數num雖然名稱相同,但是它們互不影響,
需要注意的是,函式中的變數如果省略var關鍵字,它會自動向上級作用域查找變數,一直找到全域作用域為止,
function fn() {
num2 = 20; // 區域變數
}
fn();
// 如果不呼叫函式,下面的輸出陳述句會報錯
console.log (num2);// 輸出結果:20;
從以上可以看出,在全域作用域下,添加或省略var關鍵字都可以宣告全域變數;
而在函式中,添加var關鍵字宣告的變數是區域變數,省略var關鍵字時,如果變數在當前作用域下不存在,會自動向上級作用域查找變數,
區域變數只能在函式內部使用,函式的形參也屬于區域變數,
從執行效率來說,全域變數在瀏覽器關閉頁面的時候才會銷毀,比較占用記憶體資源;而區域變數在函式執行完成后就會銷毀,比較節約記憶體資源,
📘4.5.3_作用域鏈
當在一個函式內部宣告另一個函式時,就會出現函式嵌套的效果,
當函式嵌套時,內層函式只能在外層函式作用域內執行,在內層函式執行的程序中,若需要引入某個變數,首先會在當前作用域中尋找,若未找到,則繼續向上一層級的作用域中尋找,直到全域作用域,稱這種鏈式的查詢關系為作用域鏈,
var num = 10;
function fn(){ //外部函式
var num = 20;
function fun(){ //內部函式
console.log(num);//輸出結果:20
//如果省略 var num = 20; 則輸出結果為10
}
fun();
}
fn();
📚4.6_閉包函式
📙4.6.1_什么是閉包函式
所謂"閉包"指的就是有權訪問另一函式作用域內變數(區域變數)的函式,
其主要用途:
① 可以在函式外部讀取函式內部的變數,
② 可以讓變數的值始終保存在記憶體中,
注意:由于閉包會使得函式中的變數一直被保存在記憶體中,記憶體消耗很大,所以濫用閉包可能會降低程式的處理速度,造成記憶體消耗等問題,
📗4.6.2_閉包函式的實作
常見的閉包函式創建方式就是在一個函式內部創建另一個函式,通過另一個函式訪問這個函式的區域變數,
function fn() {
var times = 0;
var c = function() {
return ++times;
};
return c;
}
var count = fn(); //保存fn()回傳的函式,此時count就是一個閉包
//訪問測驗
console.log( count() ); // 輸出結果::1
console.log( count() ); // 輸出結果::2
console.log( count() ); // 輸出結果::3
console.log( count() ); // 輸出結果::4
console.log( count() ); // 輸出結果::5
// 閉包函式就會這樣一直回圈,不會重新定義
仔細思考:閉包函式到底是什么
📚4.7_預決議
JavaScript 代碼是由瀏覽器中的 JavaScript 決議器來運行的,在運行其代碼時會進行預決議,即對 var 變數宣告和 function 函式宣告進行了決議,
📙4.7.1_預決議_var 變數宣告
console.log (num); // 輸出結果: undefined
var num = 10;
// 以下代碼由于不存在 var num2, 所以會報錯
console.log (num2); // 報錯,提示 num2 is not defined(num2 未定義)
運行結果:

以上代碼中 第 2 行在變數 num 宣告前就訪問了變數 num,卻沒有像第 5 行的 num2 一樣報錯,這是因為第 3 行代碼中的 var num 會被預決議,例如:
var num; // num 的變數宣告由于預決議而提升到前面
console.log (num); // 輸出結果: undefined
num = 10;
// 由于 num的變數宣告會被預決議,所以 console.log (num)不會報錯,并且由于賦值操作 num = 10 不會被預決議,所以此時 num 的值為 undefined
運行結果:

預決議能決議 var 變數宣告,但不能決議 var 變數宣告后面的變數賦值陳述句
📗4.7.2_預決議_function函式宣告
fn();
function fn(){
console.log('fn'); // 該函式最后會被成功呼叫
}
運行結果:

以上代碼中 fn() 函式呼叫的代碼寫在了函式宣告的前面,但函式仍然可以正確呼叫,這是因為 function 函式宣告操作會被預決議,
再例如:
console.log(fun);
fun(); // 報錯,提示fun is not a function (fun 不是一個函式)
var fun = function(){
console.log('fn');
}
運行結果:

上述代碼中 fun 不是一個函式,這是因為 var fun 變數宣告會被預決議,預決議后,fun 的值為 undefined,此時的 fun 還不是一個函式,所以無法呼叫,
只有第 2 ~ 4 行代碼執行后,才可以通過 fun() 來呼叫函式
即預決議能決議 函式宣告 和 var 變數宣告,但不能決議 var 變數宣告后的賦值陳述句
阿ken🦓在此求觀眾老爺來個三連支持一下!!!
如果你還想繼續跟阿ken🦓學習 JavaScript 的話,請看下文:
【熬夜猛肝萬字博文】學妹問我怎么入門 Javascript,百般盤問下我終于決定貢獻出自己的 JavaScript入門筆記(一)
【熬夜猛肝萬字博文】學妹問我怎么入門 Javascript,百般盤問下我終于決定貢獻出自己的 JavaScript入門筆記(二)
【熬夜猛肝萬字博文】學妹問我怎么入門 Javascript,百般盤問下我終于決定貢獻出自己的 JavaScript入門筆記(三)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/289620.html
標籤:其他
