JS函數詳解


什么是函數呢?

對於JS來說,我們可以把函數理解為任意一段代碼放在一個盒子里,在我們想要讓這段代碼執行的時候,直接執行這個盒子里的代碼就行。專業一點來講:js函數就是由事件驅動的可執行課重復只用的代碼塊。

函數定義

  • 函數定義基本有三種為聲明式賦值式構造函數式

聲明式

  • 使用function關鍵字去聲明一個函數
  • 語法:
function fn() {
	
}
//這個function就聲明了一個名為fn的函數

匿名函數(分為兩種情況)

  • 賦值式
// 賦值式的原理和我們使用var關鍵字是一個道理
// 首先我們用一個var定義一個變量,把一個函數當做值直接賦值就行了
var fn = function(){
    
}
// var定義一個fn的變量 然后函數function()賦值給fn
  • 自執行函數
//匿名函數自執行:聲明后不需要調用就直接執行
;(function(){
    console.log("自執行函數執行");
})();

構造函數式

  • 使用構造函數式我們需要用到一個關鍵字new
var object = new Object();
//這里是js語言自帶的構造函數

函數在調用上區別

  • 雖然兩種定義方式的調用都是一樣的,但是還是有一些區別的
  • 聲明式函數: 調用可以在 定義之前或者定義之后
// 可以調用
fn()
// 聲明式函數
function fn() {
	console.log('我是 fn 函數')
}
// 可以調用 fn函數
fn()
  • 賦值式函數:只能在定義之后
// 會報錯 
fn()
// 賦值式函數
var fn = function() {
	console.log('我是 fn 函數')
}
// 可以調用
fn()
  • 自執行函數:不需要調用,可以直接執行
;(function(){
            console.log("自執行函數")
})();

UTOOLS1582958471785.png

函數的參數

在定義函數的時候我們都需要使用到(),而這個()就是存放參數的地方,參數分為形參和實參
// 聲明式
function fn(形參){
    // 一段代碼
}
fn(實參);
// 賦值式
var fn = function(形參){
    // 一段代碼
}
fn(實參)

形參與實參的作用

  1. 形參
  • 形參實際上就是函數內部使用的變量,在函數外部不能使用
  • 在定義函數()中每寫一個單詞,就相當於在函數內部定義一個可以使用的變量,多個單詞之前使用,隔開
// 書寫一個參數
function fn(num) {
	// 在函數內部就可以使用 num 這個變量 
}
var fn1 = function(num) {
	// 在函數內部就可以使用 num 這個變量 
}
// 書寫兩個參數
function fun(num1, num2) {
	// 在函數內部就可以使用 num1 和 num2 這兩個變量 
}
var fun1 = function(num1, num2) {
	// 在函數內部就可以使用 num1 和 num2 這兩個變量 
}
  • 如果只有形參,沒有賦值,那么在函數內部使用的時候會出現undefined
  • 形參的值由函數調用時實參決定的
  1. 實參
  • 在函數調用時為形參賦值使用
  • 多個參數的時候需要一一對應
function fn(num1, num2){
    //這里可以使用num1和num2
}
//這樣在fn函數中調用num1和num2時,他們的值就是num1=100,num2=200;
// 如果參數沒有一一對應那么函數調用的時候就會出現undefined
fn(100,200);

UTOOLS1582959843828.png

image-20200229150422805.png

函數不定參數(可變參)-關鍵字arguments

  • 但實參傳入的值是不確定的參數個數的時候,在形參我們也不知道怎么去接收,這個時候我們就需要使用arguments來接收參數
function fn(){
            console.log(arguments);
            console.log(arguments[0]);
            console.log(arguments[1]);
            console.log(arguments[2]);
            console.log(arguments[3]);
            console.log(arguments[4]);
            console.log(arguments[5]);
            console.log(arguments[6]);
        }
fn(1,2,3,4,5,6,7)

UTOOLS1582961781569.png

函數的return的用法

  • return是返回的意思,作用就是給函數一個返回值中斷函數

返回值

  • 每一個函數自身就是一個表達式,使用return關鍵字可以是返回一個結果出去
function fn(num1, num2){
   return num1 + num2;
}
var res = fn(100, 200);
console.log(res);//結果為300

UTOOLS1582960134371.png

  • 如果沒有return返回一個結果 那么去打印函數的結果就是undefined
function fn(){
    
}
console.log(fn());// undefined

UTOOLS1582960284708.png

  • 在函數里使用return關鍵字我們可以任何數據類型當做這個函數運行后的結果

函數的特點

  • 函數就是對一段代碼的封裝,在我們想調用的時候調用
  • 函數的幾個優點
  1. 封裝代碼,使代碼更加簡潔
  2. 復用,在重復功能的時候直接調用就好
  3. 代碼執行時機,隨時可以在我們想要執行的時候執行

JS預解析機制

  • 說到預解析機制,我們需要說到變量提升函數提升
JS是一個解釋語言,在所有代碼執行前都會進行一個預解析

函數提升(整體提升)

  • 在內存中先聲明有一個變量名是函數名,並且這個名字代表的內容是一個函數
// 在代碼執行前這個函數整體已經被提升到代碼的最前面
fn();
function fn(){
    console.log("hello world");
}

變量提升(局部提升)

  • var關鍵字,在內存中先聲明有一個變量名
console.log(num);//undefined
var num = 10;
// 在代碼執行之前,這個變量被提升到代碼最前面,但是並未被賦值,所以打印的時候是undefined

作用域

  • 什么是作用域?就是一個變量可以生效的范圍
  • 變量不能再任何地方使用的,而可以使用該變量的就是變量的作用域
  • 作用域分為全局作用域局部作用域

全局作用域

  • 全局作用域是最大的作用域
  • 在全局作用域中定義的變量可以在任何地方使用
  • 頁面打開的時候,瀏覽器會自動給我們生成一個全局作用域windows
  • 全局作用域會一直存在,直到頁面關閉才銷毀
// 在頁面任何一個地方都可以使用
var num1 = 100;
var num2 = 200;

局部作用域

  • 在js中只有函數里才能出現局部作用域
  • 局部作用域中定義的變量只能在局部作用域中使用
  • 每一個函數都是一個局部作用域
function fn(){
   var num = 10;
   console.log(num);
}
//    局部作用域的作用范圍只能在函數中使用,所以這里打印is no defined
console.log(num);

UTOOLS1582964480422.png

變量使用規則

  • 有了作用域之后,變量就有了使用范圍和使用規則
  • 變量使用規則分為兩種: 范圍規則賦值規則

訪問規則

  • 當我想獲取一個變量的時候,我們稱這個行為叫做訪問
  • 獲取變量的規則
    • 首先,在自己作用域內部查找,如果有,就直接拿來使用
    • 如果沒有,就去上一級作用域查找,如果有,直接拿來使用
    • 如果沒有,就繼續向上一級作用域查找,依次類推
    • 如果一直查找到全局作用域都沒有這個變量,那么就會直接報錯 is no defined
var a = 1;
function poo(){
var num1 = 100;
function foo(){
    var num2 = 200;
    console.log(num1);//自己作用域沒有向上一層查找
    console.log(num2);//自己作用域有直接拿來用
    console.log(a);//一直查找到全局作用域
    console.log(num3);//全局作用域沒有,就直接報錯 is no defined
}
foo();
}
poo();
  • 作用訪問規則,又叫作用域查找機制
  • 作用域查找機制,只能由內向外,不能由外向內
function fn(){
    var num = 100;
}
console.log(num);//無法找到num

賦值規則

  • 當你想要給一個變量賦值的時候,我們需要先找到這個變量在給它賦值
  • 變量賦值規則
    • 先在自己的作用查找變量,查找到之后直接賦值
    • 沒有的話就向上一級作用域查找,有就直接賦值
    • 直到找到全局作用域,如果還沒有找到的話,js會將這個變量變為偽全局變量
function fn(){
num = 100;
}
console.log(num);//這里的num變成了偽全局變量,可以訪問到

總結

每當一個函數創建時,作用域鏈也被創建出來了,作用域鏈查找過程:在JS中我們調用一條數據時,會先在當前作用域進行查找,如果找不到,就從向上找父作用域的數據,還找不到就接着向上,一直找到全局作用域(window對象),window都找不到就報錯。

UTOOLS1582966479635.png


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM