JavaScript函數(shù)

JavaScript 函數(shù)定義

function functionName(parameters) {
  執(zhí)行的代碼
}

分號是用來分隔可執(zhí)行JavaScript語句。
由于函數(shù)聲明不是一個(gè)可執(zhí)行語句,所以不以分號結(jié)束。

函數(shù)表達(dá)式

JavaScript 函數(shù)可以通過一個(gè)表達(dá)式定義。

函數(shù)表達(dá)式可以存儲在變量中:

var x = function (a, b) {return a * b};

Function() 構(gòu)造函數(shù)

在以上實(shí)例中,我們了解到函數(shù)通過關(guān)鍵字 function 定義。

函數(shù)同樣可以通過內(nèi)置的 JavaScript 函數(shù)構(gòu)造器(Function())定義。

var myFunction = new Function("a", "b", "return a * b");

var x = myFunction(4, 3);
var myFunction = function (a, b) {return a * b};

var x = myFunction(4, 3);

函數(shù)提升

提升(Hoisting)是 JavaScript 默認(rèn)將當(dāng)前作用域提升到前面去的的行為。

提升(Hoisting)應(yīng)用在變量的聲明與函數(shù)的聲明。

myFunction(5);

function myFunction(y) {
    return y * y;
}

自調(diào)用(立即執(zhí)行)函數(shù)

函數(shù)表達(dá)式可以 "自調(diào)用"。

自調(diào)用表達(dá)式會自動調(diào)用。

如果表達(dá)式后面緊跟 () ,則會自動調(diào)用。

不能自調(diào)用聲明的函數(shù)。
通過添加括號,來說明它是一個(gè)函數(shù)表達(dá)式

(function () {
    var x = "Hello!!";      // 我將調(diào)用自己
})();

函數(shù)是對象

在 JavaScript 中使用 typeof 操作符判斷函數(shù)類型將返回 "function" 。

但是JavaScript 函數(shù)描述為一個(gè)對象更加準(zhǔn)確。

JavaScript 函數(shù)有 屬性 和 方法。

arguments.length 屬性返回函數(shù)調(diào)用過程接收到的參數(shù)個(gè)數(shù)

function myFunction(a, b) {
    return arguments.length;
}

toString() 方法將函數(shù)作為一個(gè)字符串返回

function myFunction(a, b) {
    return a * b;
}

var txt = myFunction.toString();

函數(shù)定義作為對象的屬性,稱之為對象方法。
函數(shù)如果用于創(chuàng)建新的對象,稱之為對象的構(gòu)造函數(shù)。

箭頭函數(shù)

ES6 新增了箭頭函數(shù)。

箭頭函數(shù)表達(dá)式的語法比普通函數(shù)表達(dá)式更簡潔。

(參數(shù)1, 參數(shù)2, …, 參數(shù)N) => { 函數(shù)聲明 }
(參數(shù)1, 參數(shù)2, …, 參數(shù)N) => 表達(dá)式(單一)
// 相當(dāng)于:(參數(shù)1, 參數(shù)2, …, 參數(shù)N) =>{ return 表達(dá)式; }

當(dāng)只有一個(gè)參數(shù)時(shí),圓括號是可選的

(單一參數(shù)) => {函數(shù)聲明}
單一參數(shù) => {函數(shù)聲明}

沒有參數(shù)的函數(shù)應(yīng)該寫成一對圓括號

() => {函數(shù)聲明}

// ES5
var x = function(x, y) {
     return x * y;
}
 
// ES6
const x = (x, y) => x * y;

有的箭頭函數(shù)都沒有自己的 this。 不適合頂一個(gè) 對象的方法。

當(dāng)我們使用箭頭函數(shù)的時(shí)候,箭頭函數(shù)會默認(rèn)幫我們綁定外層 this 的值,所以在箭頭函數(shù)中 this 的值和外層的 this 是一樣的。

箭頭函數(shù)是不能提升的,所以需要在使用之前定義。

使用 const 比使用 var 更安全,因?yàn)楹瘮?shù)表達(dá)式始終是一個(gè)常量。

如果函數(shù)部分只是一個(gè)語句,則可以省略 return 關(guān)鍵字和大括號 {},這樣做是一個(gè)比較好的習(xí)慣

JavaScript 函數(shù)參數(shù)

函數(shù)顯式參數(shù)在函數(shù)定義時(shí)列出。
函數(shù)隱式參數(shù)在函數(shù)調(diào)用時(shí)傳遞給函數(shù)真正的值。

參數(shù)規(guī)則

  • JavaScript 函數(shù)定義顯式參數(shù)時(shí)沒有指定數(shù)據(jù)類型。
  • JavaScript 函數(shù)對隱式參數(shù)沒有進(jìn)行類型檢測。
  • JavaScript 函數(shù)對隱式參數(shù)的個(gè)數(shù)沒有進(jìn)行檢測。

默認(rèn)參數(shù)

ES5 中如果函數(shù)在調(diào)用時(shí)未提供隱式參數(shù),參數(shù)會默認(rèn)設(shè)置為:undefined
有時(shí)這是可以接受的,但是建議最好為參數(shù)設(shè)置一個(gè)默認(rèn)值:

function myFunction(x, y) {
    if (y === undefined) {
          y = 0;
    } 
}

如果函數(shù)調(diào)用時(shí)設(shè)置了過多的參數(shù),參數(shù)將無法被引用,因?yàn)闊o法找到對應(yīng)的參數(shù)名。 只能使用 arguments 對象來調(diào)用。

ES6 函數(shù)可以自帶參數(shù)

ES6 支持函數(shù)帶有默認(rèn)參數(shù),就判斷 undefined 和 || 的操作

function myFunction(x, y = 10) {
    // y is 10 if not passed or undefined
    return x + y;
}
 
myFunction(0, 2) // 輸出 2
myFunction(5); // 輸出 15, y 參數(shù)的默認(rèn)值

arguments 對象

JavaScript 函數(shù)有個(gè)內(nèi)置的對象 arguments 對象。

argument 對象包含了函數(shù)調(diào)用的參數(shù)數(shù)組。

通過值傳遞參數(shù)

在函數(shù)中調(diào)用的參數(shù)是函數(shù)的隱式參數(shù)。

JavaScript 隱式參數(shù)通過值來傳遞:函數(shù)僅僅只是獲取值。

如果函數(shù)修改參數(shù)的值,不會修改顯式參數(shù)的初始值(在函數(shù)外定義)。

隱式參數(shù)的改變在函數(shù)外是不可見的。

通過對象傳遞參數(shù)

在JavaScript中,可以引用對象的值。

因此我們在函數(shù)內(nèi)部修改對象的屬性就會修改其初始的值。

修改對象屬性可作用于函數(shù)外部(全局變量)。

修改對象屬性在函數(shù)外是可見的。

JavaScript 函數(shù)調(diào)用

JavaScript 函數(shù)有 4 種調(diào)用方式。
每種方式的不同在于 this 的初始化。

this 關(guān)鍵字

一般而言,在Javascript中,this指向函數(shù)執(zhí)行時(shí)的當(dāng)前對象。

注意 this 是保留關(guān)鍵字,你不能修改 this 的值。

調(diào)用 JavaScript 函數(shù)

函數(shù)中的代碼在函數(shù)被調(diào)用后執(zhí)行。

function myFunction(a, b) {
    return a * b;
}
myFunction(10, 2);           // myFunction(10, 2) 返回 20

以上函數(shù)不屬于任何對象。但是在 JavaScript 中它始終是默認(rèn)的全局對象。

在 HTML 中默認(rèn)的全局對象是 HTML 頁面本身,所以函數(shù)是屬于 HTML 頁面。

在瀏覽器中的頁面對象是瀏覽器窗口(window 對象)。以上函數(shù)會自動變?yōu)?window 對象的函數(shù)。

myFunction() 和 window.myFunction() 是一樣的

全局對象

當(dāng)函數(shù)沒有被自身的對象調(diào)用時(shí) this 的值就會變成全局對象。

在 web 瀏覽器中全局對象是瀏覽器窗口(window 對象)。

函數(shù)作為全局對象調(diào)用,會使 this 的值成為全局對象。
使用 window 對象作為一個(gè)變量容易造成程序崩潰。

函數(shù)作為方法調(diào)用

在 JavaScript 中你可以將函數(shù)定義為對象的方法。

var myObject = {
    firstName:"John",
    lastName: "Doe",
    fullName: function () {
        return this.firstName + " " + this.lastName;
    }
}
myObject.fullName();         // 返回 "John Doe"

函數(shù)作為對象方法調(diào)用,會使得 this 的值成為對象本身

使用構(gòu)造函數(shù)調(diào)用函數(shù)

如果函數(shù)調(diào)用前使用了 new 關(guān)鍵字, 則是調(diào)用了構(gòu)造函數(shù)。

這看起來就像創(chuàng)建了新的函數(shù),但實(shí)際上 JavaScript 函數(shù)是重新創(chuàng)建的對象

// 構(gòu)造函數(shù):
function myFunction(arg1, arg2) {
    this.firstName = arg1;
    this.lastName  = arg2;
}
 
// This    creates a new object
var x = new myFunction("John","Doe");
x.firstName;                             // 返回 "John"

構(gòu)造函數(shù)的調(diào)用會創(chuàng)建一個(gè)新的對象。新對象會繼承構(gòu)造函數(shù)的屬性和方法。

構(gòu)造函數(shù)中 this 關(guān)鍵字沒有任何的值。
this 的值在函數(shù)調(diào)用實(shí)例化對象(new object)時(shí)創(chuàng)建。

作為函數(shù)方法調(diào)用函數(shù)

在 JavaScript 中, 函數(shù)是對象。JavaScript 函數(shù)有它的屬性和方法。

call() 和 apply() 是預(yù)定義的函數(shù)方法。 兩個(gè)方法可用于調(diào)用函數(shù),兩個(gè)方法的第一個(gè)參數(shù)必須是對象本身。

function myFunction(a, b) {
    return a * b;
}
myObject = myFunction.call(myObject, 10, 2);     // 返回 20
function myFunction(a, b) {
    return a * b;
}
myArray = [10, 2];
myObject = myFunction.apply(myObject, myArray);  // 返回 20

兩個(gè)方法都使用了對象本身作為第一個(gè)參數(shù)。 兩者的區(qū)別在于第二個(gè)參數(shù): apply傳入的是一個(gè)參數(shù)數(shù)組,也就是將多個(gè)參數(shù)組合成為一個(gè)數(shù)組傳入,而call則作為call的參數(shù)傳入(從第二個(gè)參數(shù)開始)。

在 JavaScript 嚴(yán)格模式(strict mode)下, 在調(diào)用函數(shù)時(shí)第一個(gè)參數(shù)會成為 this 的值, 即使該參數(shù)不是一個(gè)對象。

在 JavaScript 非嚴(yán)格模式(non-strict mode)下, 如果第一個(gè)參數(shù)的值是 null 或 undefined, 它將使用全局對象替代。

通過 call() 或 apply() 方法你可以設(shè)置 this 的值, 且作為已存在對象的新方法調(diào)用

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容