函數(function)


1、概述

  • 函數聲明
    • 采用函數表達式聲明函數時,function命令后面不帶有函數名。如果加上函數名,該函數名只在函數體內部有效,在函數體外部無效。
var print = function x(){
  console.log(typeof x);
};

x
// ReferenceError: x is not defined
    • 這種寫法的用處有兩個,一是可以在函數體內部調用自身,二是方便除錯。
  • 函數名提升
    • JavaScript 引擎將函數名視同變量名,所以采用function命令聲明函數時,整個函數會像變量聲明一樣,被提升到代碼頭部。
    • 如果像下面例子那樣,采用function命令和var賦值語句聲明同一個函數,由於存在函數提升,最后會采用var賦值語句的定義。
var f = function () {
  console.log('1');
}

function f() {
  console.log('2');
}

f() // 1

2、函數的屬性和方法

  • length屬性
    • 函數的length屬性返回函數預期傳入的參數個數,即函數定義之中的參數個數。
function f(a, b) {}
f.length // 2
// 上面代碼定義了空函數f,它的length屬性就是定義時的參數個數。不管調用時輸入了多少個參數,length屬性始終等於2。

// length屬性提供了一種機制,判斷定義時和調用時參數的差異,以便實現面向對象編程的“方法重載”(overload)。
  • toString()
    • 函數的toString()方法返回一個字符串,內容是函數的源碼。

3、函數作用域

  • 定義
    • 作用域(scope)指的是變量存在的范圍。在 ES5 的規范中,JavaScript 只有兩種作用域:一種是全局作用域,變量在整個程序中一直存在,所有地方都可以讀取;另一種是函數作用域,變量只在函數內部存在。ES6 又新增了塊級作用域。
    • 注意,對於var命令來說,局部變量只能在函數內部聲明,在其他區塊中聲明,一律都是全局變量。
  • 函數內部變量提升
    • 與全局作用域一樣,函數作用域內部也會產生“變量提升”現象。var命令聲明的變量,不管在什么位置,變量聲明都會被提升到函數體的頭部。
  • 函數本身作用域
    • 函數本身也是一個值,也有自己的作用域。它的作用域與變量一樣,就是其聲明時所在的作用域,與其運行時所在的作用域無關(詞法作用域)。
var a = 1;
var x = function () {
  console.log(a);
};

function f() {
  var a = 2;
  x();
}

f() // 1

4、參數

  • 參數的省略
    • 函數參數不是必需的,JavaScript 允許省略參數。
function f(a, b) {
  return a;
}

f(1, 2, 3) // 1
f(1) // 1
f() // undefined

f.length // 2

// 沒有辦法只省略靠前的參數,而保留靠后的參數。如果一定要省略靠前的參數,只有顯式傳入undefined。
  • 傳遞方式
    • 函數參數如果是原始類型的值(數值、字符串、布爾值),傳遞方式是傳值傳遞(passes by value)。這意味着,在函數體內修改參數值,不會影響到函數外部。
var p = 2;

function f(p) {
  p = 3;
}
f(p);

p // 2
// 上面代碼中,變量p是一個原始類型的值,傳入函數f的方式是傳值傳遞。因此,在函數內部,p的值是原始值的拷貝,無論怎么修改,都不會影響到原始值。
    • 如果函數參數是復合類型的值(數組、對象、其他函數),傳遞方式是傳址傳遞(pass by reference)。也就是說,傳入函數的原始值的地址,因此在函數內部修改參數,將會影響到原始值。
var obj = { p: 1 };

function f(o) {
  o.p = 2;
}
f(obj);

obj.p // 2
    • 如果函數內部修改的,不是參數對象的某個屬性,而是替換掉整個參數,這時不會影響到原始值。
var obj = [1, 2, 3];

function f(o) {
  o = [2, 3, 4];
}
f(obj);

obj // [1, 2, 3]

// 這是因為,形式參數(o)的值實際是參數obj的地址,重新對o賦值導致o指向另一個地址,保存在原地址上的值當然不受影響。
  • 同名參數
    • 如果有同名的參數,則取最后出現的那個值;即使后面的a沒有值或被省略,也是以其為准。
function f(a, a) {
  console.log(a);
}

f(1, 2) // 2

function f(a, a) {
  console.log(a);
}

f(1) // undefined
  • arguments對象
    • 定義
      • 正常模式下,arguments對象可以在運行時修改。
      • 嚴格模式下,arguments對象與函數參數不具有聯動關系。也就是說,修改arguments對象不會影響到實際的函數參數。
    • 與數組的關系
      • 它是類似數組的對象,可轉換為數組。


免責聲明!

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



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