JavaScript ES5 函數(shù)從基礎(chǔ)到高級(jí)應(yīng)用全解析
函數(shù)是 JavaScript(ES5)的核心語(yǔ)法單元,不僅承擔(dān)代碼復(fù)用功能,更是實(shí)現(xiàn)作用域隔離、異步編程和模塊化的基礎(chǔ)。
一、函數(shù)核心概念與專(zhuān)有名詞解析
| 專(zhuān)有名詞 | 定義與說(shuō)明 |
|---|---|
| 函數(shù)聲明(Function Declaration) | 通過(guò) function 關(guān)鍵字顯式定義函數(shù)名的方式,支持 “函數(shù)提升”,可在聲明前調(diào)用。 |
| 函數(shù)表達(dá)式(Function Expression) | 將匿名 / 命名函數(shù)賦值給變量的方式,不支持函數(shù)提升,需賦值后調(diào)用。 |
| arguments 對(duì)象 | 函數(shù)內(nèi)部的類(lèi)數(shù)組對(duì)象(具有 length 屬性但無(wú)數(shù)組方法),存儲(chǔ)所有傳入的實(shí)參。 |
| this 綁定 | 函數(shù)執(zhí)行時(shí)的 “上下文對(duì)象”,指向由調(diào)用方式?jīng)Q定(非定義位置),ES5 無(wú)箭頭函數(shù)綁定規(guī)則。 |
| IIFE(立即執(zhí)行函數(shù)) | 全稱(chēng) Immediately Invoked Function Expression,聲明后立即執(zhí)行,用于創(chuàng)建獨(dú)立作用域。 |
| 作用域鏈(Scope Chain) | 函數(shù)嵌套時(shí)形成的變量查找鏈,從當(dāng)前函數(shù)作用域向上遍歷至全局作用域。 |
| 閉包(Closure) | 有權(quán)訪(fǎng)問(wèn)另一個(gè)函數(shù)作用域中變量的函數(shù),本質(zhì)是作用域鏈的 “延長(zhǎng)保留”。 |
| 回調(diào)函數(shù)(Callback) | 作為參數(shù)傳遞給另一個(gè)函數(shù)的函數(shù),在特定時(shí)機(jī)(如異步操作完成)被調(diào)用。 |
二、函數(shù)定義與聲明:兩種方式的細(xì)節(jié)對(duì)比
函數(shù)有 “函數(shù)聲明” 和 “函數(shù)表達(dá)式” 兩種定義方式,二者在提升特性、作用域表現(xiàn)上存在關(guān)鍵差異,需結(jié)合實(shí)例理解。
2.1 函數(shù)聲明(支持函數(shù)提升)
語(yǔ)法與實(shí)例
// 函數(shù)聲明:function 關(guān)鍵字 + 函數(shù)名 + 參數(shù)列表 + 函數(shù)體
function calculateSum(a, b) {
// 函數(shù)體:實(shí)現(xiàn)求和邏輯
return a + b;
}
// 關(guān)鍵特性:函數(shù)提升(聲明前調(diào)用仍可執(zhí)行)
console.log(calculateSum(3, 5)); // 輸出:8(正常執(zhí)行,無(wú)報(bào)錯(cuò))專(zhuān)有名詞補(bǔ)充:函數(shù)提升(Function Hoisting)
ES5 解析代碼時(shí),會(huì)將函數(shù)聲明的 “函數(shù)名 + 函數(shù)體” 整體提升至當(dāng)前作用域頂部,因此可在聲明前調(diào)用。但需注意:僅函數(shù)聲明支持提升,函數(shù)表達(dá)式不支持。
2.2 函數(shù)表達(dá)式(不支持函數(shù)提升)
匿名函數(shù)表達(dá)式即 “無(wú)函數(shù)名的函數(shù)”,賦值后通過(guò)變量名調(diào)用,是回調(diào)函數(shù)、一次性邏輯封裝的常用形式。
// 1. 聲明變量 fn,賦值為一個(gè)匿名函數(shù)(函數(shù)表達(dá)式的核心語(yǔ)法)
// 右側(cè) function(){} 是匿名函數(shù),無(wú)函數(shù)名,作為值賦值給 fn
var fn = function(a, b) {
// 函數(shù)內(nèi)部邏輯:計(jì)算兩數(shù)之和
// 內(nèi)部可訪(fǎng)問(wèn)參數(shù) a、b,以及外部作用域的變量(后續(xù)詳解)
var sum = a + b;
console.log("匿名函數(shù)內(nèi)部:a + b =", sum); // 輸出計(jì)算結(jié)果
return sum; // 返回結(jié)果給外部調(diào)用者
};
// 2. 調(diào)用函數(shù)表達(dá)式:通過(guò)變量名 fn 調(diào)用,傳入實(shí)參
// 外部通過(guò)變量名觸發(fā)函數(shù)執(zhí)行,獲取返回值
var result = fn(3, 5);
console.log("外部訪(fǎng)問(wèn)函數(shù)返回值:", result); // 輸出:外部訪(fǎng)問(wèn)函數(shù)返回值:8
// 關(guān)鍵注意:匿名函數(shù)本身無(wú)名字,無(wú)法在內(nèi)部通過(guò)函數(shù)名遞歸(需用 arguments.callee)
var factorial = function(n) {
if (n === 1) return 1;
// 匿名函數(shù)內(nèi)部無(wú)法通過(guò)“函數(shù)名”遞歸,需用 arguments.callee 指向當(dāng)前函數(shù)
return n * arguments.callee(n - 1);
};
console.log("匿名函數(shù)遞歸(階乘):", factorial(5)); // 輸出:120命名函數(shù)表達(dá)式(帶函數(shù)名)
命名函數(shù)表達(dá)式是 “給函數(shù)本身指定名字的表達(dá)式”,函數(shù)名僅在函數(shù)內(nèi)部可用,外部仍通過(guò)變量名調(diào)用,適用于需要在函數(shù)內(nèi)部遞歸、調(diào)試(函數(shù)名會(huì)顯示在調(diào)用棧中)的場(chǎng)景。
// 1. 聲明變量 calculate,賦值為一個(gè)“帶名字的函數(shù)”(函數(shù)名:multiply)
// 右側(cè) function multiply(a, b){} 是命名函數(shù),函數(shù)名 multiply 僅內(nèi)部可用
var calculate = function multiply(a, b) {
// 函數(shù)內(nèi)部可通過(guò)函數(shù)名 multiply 訪(fǎng)問(wèn)自身(用于遞歸)
console.log("命名函數(shù)內(nèi)部:函數(shù)名 =", multiply.name); // 輸出:命名函數(shù)內(nèi)部:函數(shù)名 = multiply
return a * b;
};
// 2. 外部調(diào)用:只能通過(guò)變量名 calculate 調(diào)用,無(wú)法直接用 multiply
console.log("外部調(diào)用命名函數(shù)表達(dá)式:", calculate(4, 6)); // 輸出:24
// console.log(multiply(4, 6)); // 報(bào)錯(cuò):multiply is not defined(外部無(wú)法訪(fǎng)問(wèn)函數(shù)內(nèi)部的名字)
// 3. 命名函數(shù)表達(dá)式的核心優(yōu)勢(shì):內(nèi)部遞歸更清晰(無(wú)需依賴(lài) arguments.callee)
var fibonacci = function fib(n) {
if (n <= 2) return 1;
// 內(nèi)部通過(guò)函數(shù)名 fib 遞歸,語(yǔ)義更清晰,避免 arguments.callee 的歧義
return fib(n - 1) + fib(n - 2);
};
console.log("命名函數(shù)遞歸(斐波那契):", fibonacci(6)); // 輸出:8(1,1,2,3,5,8)函數(shù)表達(dá)式的作用域訪(fǎng)問(wèn)規(guī)則:內(nèi)部與外部能否互相訪(fǎng)問(wèn)?
函數(shù)表達(dá)式的 “內(nèi)外訪(fǎng)問(wèn)權(quán)限” 由 ES5 作用域規(guī)則決定:ES5 僅支持 “全局作用域” 和 “函數(shù)作用域”,無(wú)塊級(jí)作用域,訪(fǎng)問(wèn)權(quán)限遵循 “內(nèi)層可訪(fǎng)問(wèn)外層,外層不可訪(fǎng)問(wèn)內(nèi)層” 的原則。
核心規(guī)則總結(jié)
| 訪(fǎng)問(wèn)方向 | 是否允許 | 底層邏輯 |
|---|---|---|
| 函數(shù)內(nèi)部訪(fǎng)問(wèn)外部變量 | 允許 | 作用域鏈規(guī)則:內(nèi)部作用域會(huì)向上遍歷外層作用域,直到找到變量或到達(dá)全局作用域。 |
| 函數(shù)外部訪(fǎng)問(wèn)內(nèi)部變量 | 不允許 | 函數(shù)作用域隔離:內(nèi)部變量?jī)H在函數(shù)內(nèi)部生效,外部無(wú)訪(fǎng)問(wèn)路徑。 |
語(yǔ)法與實(shí)例(匿名 / 命名兩種形式)
// 1. 匿名函數(shù)表達(dá)式:無(wú)函數(shù)名,賦值給變量
var calculateMultiply = function(a, b) {
return a * b;
};
// 2. 命名函數(shù)表達(dá)式:函數(shù)名僅在內(nèi)部可用(用于遞歸或調(diào)試)
var calculateDivide = function divide(a, b) {
console.log(divide.name); // 輸出:divide(內(nèi)部訪(fǎng)問(wèn)函數(shù)名)
if (b === 0) return "除數(shù)不能為0";
return a / b;
};
// 關(guān)鍵特性:無(wú)函數(shù)提升(聲明前調(diào)用會(huì)報(bào)錯(cuò))
// console.log(calculateMultiply(4, 6)); // 報(bào)錯(cuò):calculateMultiply is not a function(若放在賦值前)
console.log(calculateMultiply(4, 6)); // 輸出:24(賦值后調(diào)用正常)
console.log(calculateDivide(10, 2)); // 輸出:5兩種定義方式的核心差異
| 對(duì)比維度 | 函數(shù)聲明 | 函數(shù)表達(dá)式 |
|---|---|---|
| 提升支持 | 支持(整體提升至作用域頂部) | 不支持(變量提升但值為 undefined) |
| 函數(shù)名 | 必須顯式定義 | 可選(匿名 / 命名,命名僅內(nèi)部可用) |
| 適用場(chǎng)景 | 獨(dú)立函數(shù)(如工具函數(shù)) | 賦值給變量、作為參數(shù)(如回調(diào)函數(shù)) |
三、函數(shù)內(nèi)部核心屬性:arguments 與 this
函數(shù)內(nèi)部有兩個(gè)特殊屬性:arguments(處理參數(shù))和 this(處理上下文),二者是實(shí)現(xiàn)靈活邏輯的關(guān)鍵。
3.1 arguments 對(duì)象:類(lèi)數(shù)組的參數(shù)集合
定義與特性
arguments 是函數(shù)內(nèi)部的類(lèi)數(shù)組對(duì)象,存儲(chǔ)所有傳入的實(shí)參,支持:
- 通過(guò)索引訪(fǎng)問(wèn)參數(shù)(如
arguments[0]獲取第一個(gè)實(shí)參); length屬性獲取實(shí)參個(gè)數(shù);callee屬性指向當(dāng)前函數(shù)(用于匿名函數(shù)遞歸)。
實(shí)踐實(shí)例
// 實(shí)例1:處理不確定個(gè)數(shù)的參數(shù)(求和)
function sum() {
var total = 0;
// 遍歷 arguments(類(lèi)數(shù)組,需用 for 循環(huán),無(wú) forEach 方法)
for (var i = 0; i < arguments.length; i++) {
// 過(guò)濾非數(shù)字參數(shù)(增強(qiáng)魯棒性)
if (typeof arguments[i] === "number") {
total += arguments[i];
}
}
return total;
}
console.log(sum(1, 2, 3)); // 輸出:6
console.log(sum(10, 20, "a", 30)); // 輸出:60(忽略非數(shù)字參數(shù))
// 實(shí)例2:arguments.callee 實(shí)現(xiàn)匿名函數(shù)遞歸(計(jì)算階乘)
var factorial = function(n) {
if (n === 1) return 1;
// callee 指向當(dāng)前函數(shù),避免依賴(lài)外部變量名
return n * arguments.callee(n - 1);
};
console.log(factorial(5)); // 輸出:120(5! = 5*4*3*2*1)3.2 this 綁定:動(dòng)態(tài)上下文對(duì)象
定義與核心規(guī)則
this 是函數(shù)執(zhí)行時(shí)的 “上下文對(duì)象”,其指向由調(diào)用方式?jīng)Q定,與函數(shù)定義位置無(wú)關(guān),ES5 中常見(jiàn)綁定場(chǎng)景如下:
實(shí)踐實(shí)例(4 種核心綁定場(chǎng)景)
// 場(chǎng)景1:全局調(diào)用 -> this 指向全局對(duì)象(瀏覽器:window,Node:global)
function getGlobalContext() {
console.log(this === window); // 瀏覽器環(huán)境輸出:true
console.log(this === global); // Node 環(huán)境輸出:true
}
getGlobalContext();
// 場(chǎng)景2:對(duì)象方法調(diào)用 -> this 指向調(diào)用對(duì)象
var user = {
name: "張三",
age: 25,
introduce: function() {
return `我是${this.name},今年${this.age}歲`;
}
};
console.log(user.introduce()); // 輸出:我是張三,今年25歲
// 場(chǎng)景3:call/apply 強(qiáng)制綁定 -> this 指向指定對(duì)象
var anotherUser = { name: "李四", age: 30 };
// call:參數(shù)列表傳遞(逗號(hào)分隔)
console.log(user.introduce.call(anotherUser)); // 輸出:我是李四,今年30歲
// apply:參數(shù)數(shù)組傳遞
console.log(user.introduce.apply(anotherUser)); // 輸出:我是李四,今年30歲
// 場(chǎng)景4:bind 延遲綁定 -> 返回 this 綁定后的新函數(shù)
var boundIntroduce = user.introduce.bind(anotherUser);
setTimeout(boundIntroduce, 1000); // 1秒后輸出:我是李四,今年30歲關(guān)鍵提醒
- 避免在全局作用域?yàn)E用
this(易導(dǎo)致變量污染); - 函數(shù)作為回調(diào)時(shí)(如定時(shí)器、數(shù)組
forEach),this默認(rèn)指向全局對(duì)象(需通過(guò)bind手動(dòng)綁定)。
四、立即執(zhí)行函數(shù)(IIFE):作用域隔離的核心工具
IIFE 的核心作用是 “創(chuàng)建獨(dú)立作用域,避免變量污染全局”,尤其適用于模塊化開(kāi)發(fā)和循環(huán)變量隔離。
4.1 IIFE 語(yǔ)法與原理
核心語(yǔ)法(兩種常用形式)
// 形式1:外層括號(hào)包裹函數(shù)體 + 執(zhí)行括號(hào)(推薦,語(yǔ)義清晰)
(function(a, b) {
console.log("IIFE 形式1:" + (a + b)); // 輸出:IIFE 形式1:15
})(10, 5);
// 形式2:函數(shù)體括號(hào) + 執(zhí)行括號(hào)(省略外層括號(hào),利用運(yùn)算符優(yōu)先級(jí))
(function(a, b) {
console.log("IIFE 形式2:" + (a * b)); // 輸出:IIFE 形式2:50
}(25, 2));
// 簡(jiǎn)化形式(利用一元運(yùn)算符,如 !、+、-,省略外層括號(hào))
!function(a) {
console.log("IIFE 簡(jiǎn)化形式:" + a); // 輸出:IIFE 簡(jiǎn)化形式:8
}(8);原理:為什么需要括號(hào)?
ES5 解析器會(huì)將以 function 開(kāi)頭的語(yǔ)句視為 “函數(shù)聲明”,而函數(shù)聲明不能直接調(diào)用(需通過(guò)函數(shù)名)。通過(guò)括號(hào)包裹,可將其轉(zhuǎn)為 “函數(shù)表達(dá)式”,從而支持立即執(zhí)行。
4.2 IIFE 核心應(yīng)用:解決循環(huán)變量污染
問(wèn)題場(chǎng)景(未用 IIFE 的缺陷)
// 問(wèn)題:循環(huán)中 var 聲明的變量共享,導(dǎo)致定時(shí)器輸出異常
for (var i = 0; i < 3; i++) {
setTimeout(function() {
console.log("未用 IIFE:" + i); // 輸出:3 3 3(循環(huán)結(jié)束后 i 已變?yōu)?3)
}, 100);
}解決方案(IIFE 隔離作用域)
// 方案:通過(guò) IIFE 將每次迭代的 i 傳入獨(dú)立作用域
for (var i = 0; i < 3; i++) {
(function(j) {
// j 是 IIFE 的參數(shù),每次迭代獨(dú)立保存 i 的當(dāng)前值
setTimeout(function() {
console.log("用 IIFE:" + j); // 輸出:0 1 2(正常輸出每次迭代的 i)
}, 100);
})(i); // 將當(dāng)前 i 作為實(shí)參傳入
}五、閉包(Closure):函數(shù)與作用域的進(jìn)階融合
閉包定義為 “有權(quán)訪(fǎng)問(wèn)另一個(gè)函數(shù)作用域中變量的函數(shù)”,其本質(zhì)是作用域鏈的延長(zhǎng)保留,是 ES5 中實(shí)現(xiàn) “狀態(tài)保存” 和 “模塊化” 的核心手段。
5.1 閉包的創(chuàng)建與底層原理
核心條件(滿(mǎn)足以下 3 點(diǎn)即形成閉包)
- 函數(shù)嵌套(內(nèi)層函數(shù)嵌套在外層函數(shù)中);
- 內(nèi)層函數(shù)引用外層函數(shù)的變量 / 參數(shù);
- 外層函數(shù)返回內(nèi)層函數(shù)(或內(nèi)層函數(shù)被外部引用)。
實(shí)踐實(shí)例(計(jì)數(shù)器:閉包保存狀態(tài))
// 外層函數(shù):定義局部變量 count
function createCounter() {
var count = 0; // 被閉包引用的外層變量,不會(huì)被垃圾回收
var step = 1; // 額外參數(shù),演示多變量保存
// 內(nèi)層函數(shù):引用 count 和 step,形成閉包
return {
increment: function() {
count += step;
return count;
},
setStep: function(newStep) {
step = newStep; // 可通過(guò)閉包修改外層變量
}
};
}
// 調(diào)用外層函數(shù),獲取閉包對(duì)象(保存 count 和 step 的狀態(tài))
var counter1 = createCounter();
var counter2 = createCounter(); // 獨(dú)立閉包,狀態(tài)不共享
// 操作 counter1
console.log(counter1.increment()); // 輸出:1(count=1,step=1)
counter1.setStep(2); // 修改 step 為 2
console.log(counter1.increment()); // 輸出:3(count=1+2=3)
// 操作 counter2(與 counter1 狀態(tài)獨(dú)立)
console.log(counter2.increment()); // 輸出:1(count=1,step=1)原理補(bǔ)充:垃圾回收機(jī)制
正常情況下,函數(shù)執(zhí)行完后,其局部變量會(huì)被垃圾回收(釋放內(nèi)存)。但閉包中,由于內(nèi)層函數(shù)引用外層變量,外層函數(shù)的作用域會(huì)被保留,變量不會(huì)被回收,從而實(shí)現(xiàn) “狀態(tài)持久化”。
5.2 閉包的核心應(yīng)用場(chǎng)景
場(chǎng)景 1:實(shí)現(xiàn)私有變量(模塊化基礎(chǔ))
// 模塊:通過(guò)閉包隱藏內(nèi)部變量,僅暴露指定方法
var userModule = (function() {
// 私有變量:僅內(nèi)部可訪(fǎng)問(wèn),外部無(wú)法直接修改
var privateName = "張三";
var privateAge = 25;
// 暴露的公共方法(閉包,引用私有變量)
return {
getName: function() {
return privateName;
},
setAge: function(newAge) {
// 可在方法中添加校驗(yàn)邏輯,保證數(shù)據(jù)安全
if (typeof newAge === "number" && newAge > 0) {
privateAge = newAge;
}
return privateAge;
},
getInfo: function() {
return `姓名:${privateName},年齡:${privateAge}`;
}
};
})();
// 外部訪(fǎng)問(wèn):只能通過(guò)暴露的方法操作,無(wú)法直接修改私有變量
console.log(userModule.getName()); // 輸出:張三
console.log(userModule.setAge(28)); // 輸出:28
console.log(userModule.getInfo()); // 輸出:姓名:張三,年齡:28
console.log(userModule.privateName); // 輸出:undefined(私有變量不可直接訪(fǎng)問(wèn))場(chǎng)景 2:異步操作中的變量綁定
// 場(chǎng)景:異步請(qǐng)求中保留請(qǐng)求參數(shù)(如 AJAX 回調(diào))
function fetchData(url) {
// 模擬 AJAX 異步請(qǐng)求
setTimeout(function() {
// 閉包引用外層變量 url,即使 fetchData 執(zhí)行完,url 仍被保留
console.log(`請(qǐng)求地址:${url},模擬返回?cái)?shù)據(jù)成功`);
}, 1000);
}
fetchData("https://api.example.com/user"); // 1秒后輸出:請(qǐng)求地址:https://api.example.com/user,模擬返回?cái)?shù)據(jù)成功
fetchData("https://api.example.com/order"); // 1秒后輸出:請(qǐng)求地址:https://api.example.com/order,模擬返回?cái)?shù)據(jù)成功5.3 閉包的注意事項(xiàng)
- 內(nèi)存占用問(wèn)題:閉包會(huì)保留外層作用域,濫用可能導(dǎo)致內(nèi)存泄漏(如 DOM 事件綁定后未解綁),建議不用時(shí)手動(dòng)解除引用(如
counter = null); - 變量共享問(wèn)題:若閉包引用循環(huán)變量,需通過(guò) IIFE 隔離(參考前文循環(huán)變量示例);
- this 指向問(wèn)題:閉包中的
this默認(rèn)指向全局對(duì)象,需通過(guò)bind或變量保存(如var self = this)。
六、函數(shù)調(diào)用的進(jìn)階:回調(diào)函數(shù)與異步編程
“函數(shù)可作為返回值或參數(shù)”,其中 “作為參數(shù)” 即回調(diào)函數(shù),是 ES5 中實(shí)現(xiàn)異步編程的核心方式(如定時(shí)器、AJAX、事件綁定)。
6.1 回調(diào)函數(shù)的定義與分類(lèi)
核心定義
回調(diào)函數(shù)是 “作為參數(shù)傳遞給另一個(gè)函數(shù)的函數(shù)”,在被調(diào)用函數(shù)執(zhí)行到特定時(shí)機(jī)時(shí)觸發(fā),分為同步回調(diào)和異步回調(diào)。
實(shí)踐實(shí)例
// 1. 同步回調(diào)(立即執(zhí)行,如數(shù)組遍歷)
var numbers = [1, 2, 3, 4];
// forEach 的參數(shù)是同步回調(diào),遍歷完成后立即執(zhí)行
numbers.forEach(function(item, index) {
console.log(`索引${index}:${item * 2}`); // 輸出:索引0:2 索引1:4 索引2:6 索引3:8
});
// 2. 異步回調(diào)(延遲執(zhí)行,如定時(shí)器)
function loadData(callback) {
console.log("開(kāi)始加載數(shù)據(jù)...");
// 模擬異步操作(如 AJAX 請(qǐng)求)
setTimeout(function() {
var data = { name: "李四", age: 30 };
callback(data); // 異步完成后調(diào)用回調(diào),傳遞數(shù)據(jù)
}, 1500);
}
// 調(diào)用函數(shù)并傳入回調(diào)
loadData(function(result) {
console.log("加載完成,數(shù)據(jù):", result); // 1.5秒后輸出:加載完成,數(shù)據(jù):{ name: '李四', age: 30 }
});
console.log("加載請(qǐng)求已發(fā)送(不阻塞后續(xù)代碼)"); // 先輸出:加載請(qǐng)求已發(fā)送(不阻塞后續(xù)代碼)6.2 回調(diào)函數(shù)的常見(jiàn)應(yīng)用
- DOM 事件綁定:如
button.onclick = function() {}; - AJAX 請(qǐng)求:如
XMLHttpRequest的onreadystatechange事件; - 定時(shí)器:如
setTimeout、setInterval; - 工具函數(shù):如
Array.prototype.map、filter、reduce。
七、補(bǔ)充:函數(shù)的其他關(guān)鍵細(xì)節(jié)
7.1 函數(shù)的 length 屬性
“function.length 表示函數(shù)希望接受的命名參數(shù)個(gè)數(shù)”,即形參個(gè)數(shù)(不包含剩余參數(shù))。
function add(a, b) {
return a + b;
}
function multiply(a, b, c) {
return a * b * c;
}
console.log(add.length); // 輸出:2(形參個(gè)數(shù)為 2)
console.log(multiply.length); // 輸出:3(形參個(gè)數(shù)為 3)7.2 函數(shù)作為對(duì)象(Function 類(lèi)型)
ES5 中函數(shù)是 Function 類(lèi)型的實(shí)例,因此具有屬性和方法(如 name、call、apply、bind)。
function greet(name) {
return `Hello, ${name}`;
}
console.log(greet instanceof Function); // 輸出:true(函數(shù)是 Function 實(shí)例)
console.log(greet.name); // 輸出:greet(函數(shù)名屬性)
console.log(greet.toString()); // 輸出函數(shù)的源代碼:function greet(name) { return `Hello, ${name}`; }總結(jié)
ES5 函數(shù)的核心知識(shí)點(diǎn)可歸納為 “三大基礎(chǔ) + 兩大進(jìn)階”:
- 三大基礎(chǔ):函數(shù)定義(聲明 / 表達(dá)式)、內(nèi)部屬性(arguments/this)、調(diào)用方式(普通 / 方法 /call/apply/bind);
- 兩大進(jìn)階:IIFE(作用域隔離)、閉包(狀態(tài)保存與模塊化)。
函數(shù)是 JavaScript 編程的 “基石”,掌握以上內(nèi)容不僅能應(yīng)對(duì) ES5 環(huán)境的開(kāi)發(fā)需求,也能為理解 ES6+ 的箭頭函數(shù)、解構(gòu)賦值等特性奠定基礎(chǔ)。建議結(jié)合實(shí)例反復(fù)調(diào)試,重點(diǎn)突破 this 綁定和閉包的細(xì)節(jié)~
到此這篇關(guān)于JavaScript ES5 函數(shù)從基礎(chǔ)到高級(jí)應(yīng)用全解析的文章就介紹到這了,更多相關(guān)JavaScript ES5 函數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- JS利用ES6和ES5分別實(shí)現(xiàn)長(zhǎng)整數(shù)和字節(jié)數(shù)組互轉(zhuǎn)
- JavaScript的ES5實(shí)現(xiàn)繼承的4種常用方法小結(jié)
- JS?ES5創(chuàng)建常量詳解
- js定義類(lèi)的方法示例【ES5與ES6】
- 詳解vue-cli+es6引入es5寫(xiě)的js(兩種方法)
- JS實(shí)現(xiàn)集合的交集、補(bǔ)集、差集、去重運(yùn)算示例【ES5與ES6寫(xiě)法】
- JavaScript設(shè)計(jì)模式之原型模式分析【ES5與ES6】
- JavaScript ES5標(biāo)準(zhǔn)中新增的Array方法
相關(guān)文章
使用JSX 建立組件 Parser(解析器)開(kāi)發(fā)的示例
這篇文章主要介紹了使用JSX 建立組件 Parser(解析器)開(kāi)發(fā)的示例(前端組件化)本文重點(diǎn)講述我們?nèi)绾螐?開(kāi)始搭建一個(gè)組件系統(tǒng),基于標(biāo)記語(yǔ)言的Parser的一種風(fēng)格2021-04-04
用js實(shí)現(xiàn)簡(jiǎn)單算法的實(shí)例代碼
下面小編就為大家?guī)?lái)一篇用js實(shí)現(xiàn)簡(jiǎn)單算法的實(shí)例代碼。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-09-09
Layui table field初始化加載時(shí)進(jìn)行隱藏的方法
今天小編就為大家分享一篇Layui table field初始化加載時(shí)進(jìn)行隱藏的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-09-09
TypeScript基礎(chǔ)類(lèi)型完全指南(附示例代碼)
TypeScript是JavaScript的一個(gè)超集,支持ES6的標(biāo)準(zhǔn),它擴(kuò)展了JavaScript的語(yǔ)法,這篇文章主要介紹了TypeScript基礎(chǔ)類(lèi)型完全指南的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-11-11
微信小程序?qū)崿F(xiàn)通過(guò)js操作wxml的wxss屬性示例
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)通過(guò)js操作wxml的wxss屬性,結(jié)合實(shí)例形式分析了微信小程序使用js操作wxml的wxss屬性相關(guān)原理、實(shí)現(xiàn)技巧與操作注意事項(xiàng),需要的朋友可以參考下2018-12-12
JavaScript實(shí)現(xiàn)搜索高亮功能詳解
這篇文章主要介紹了JavaScript實(shí)現(xiàn)搜索高亮功能,搜索功能是常見(jiàn)的需求之一,為了提升用戶(hù)體驗(yàn),我們可以通過(guò)高亮顯示搜索結(jié)果中的關(guān)鍵詞來(lái)幫助用戶(hù)快速定位信息,需要的朋友可以參考下2025-05-05

