JavaScript apply 方法示例詳解
在 JavaScript 中,
apply是函數(shù)對象(Function)自帶的一個非常重要的方法,與call和bind并稱為“函數(shù)三兄弟”。它們都屬于函數(shù)的“顯式調(diào)用”方式,常用于動態(tài)改變函數(shù)的執(zhí)行上下文(this指向)。本文將帶你全面理解apply的語法、作用機制、實際應(yīng)用場景,以及與call、bind的區(qū)別,幫助你在開發(fā)中靈活運用它提升代碼的復用性與靈活性。
一、函數(shù)是“對象”,apply 是“方法”
在 JavaScript 中,函數(shù)是一等公民(First-Class Object),這意味著函數(shù)本質(zhì)上是對象,具備一些自帶的方法,例如 apply、call、bind 等。
apply 是定義在 Function.prototype 上的方法,任何函數(shù)都可以通過繼承使用它。
換句話說:
typeof Function.prototype.apply === 'function' // true
二、apply 的基本語法
func.apply(thisArg, [argsArray])
參數(shù)說明:
- func:調(diào)用
apply的目標函數(shù)。 - thisArg:函數(shù)在執(zhí)行時綁定的
this值(上下文對象)。 - argsArray:一個“類數(shù)組對象”或“數(shù)組”,表示要傳遞給目標函數(shù)的參數(shù)列表。
示例:
function greet(language1, language2) {
console.log(`${this.name} 會說 ${language1} 和 ${language2}`);
}
const person = { name: '小明' };
greet.apply(person, ['中文', '英文']);
// 輸出:小明 會說 中文 和 英文在這個例子中,greet 原本的 this 是 undefined,但我們通過 apply 把 this 顯式綁定到了 person 對象上。
三、apply 與 call、bind 的區(qū)別
雖然 apply、call、bind 都可以顯式地設(shè)置函數(shù)的執(zhí)行上下文,但三者的用法略有不同:
| 方法名 | 是否立即調(diào)用 | 參數(shù)形式 |
|---|---|---|
| call | 是 | 依次傳入?yún)?shù)(逗號分隔) |
| apply | 是 | 參數(shù)打包成一個數(shù)組 |
| bind | 否(返回新函數(shù)) | 依次傳入?yún)?shù)(逗號分隔) |
示例對比:
function sayHello(a, b) {
console.log(`${this.name}:${a} + $`);
}
const obj = { name: '小紅' };
// call
sayHello.call(obj, '早上好', '下午好');
// apply
sayHello.apply(obj, ['早上好', '下午好']);
// bind
const newFunc = sayHello.bind(obj, '早上好', '下午好');
newFunc(); // 手動調(diào)用四、apply 的核心用途場景
1. 改變函數(shù)的 this 指向
這是最常見的用法之一,尤其在一些回調(diào)函數(shù)或事件處理函數(shù)中使用 apply 來設(shè)置上下文環(huán)境。
function introduce(age) {
console.log(`我是 ${this.name},今年 ${age} 歲`);
}
const student = { name: '小李' };
introduce.apply(student, [20]); // 輸出:我是 小李,今年 20 歲2. 借用其他對象的方法(函數(shù)借用)
apply 非常適合用來實現(xiàn)“對象之間的方法復用”,這在類數(shù)組對象處理時特別常見。
例如,類數(shù)組轉(zhuǎn)真正數(shù)組:
function toArray() {
return Array.prototype.slice.apply(arguments);
}
console.log(toArray(1, 2, 3)); // [1, 2, 3]3. 獲取數(shù)組中的最大值或最小值
在不知道數(shù)組長度的情況下,apply 可以把數(shù)組“拆開”傳給 Math.max、Math.min:
const arr = [5, 1, 99, 34]; const max = Math.max.apply(null, arr); // 99 const min = Math.min.apply(null, arr); // 1
如果你用 Math.max(arr) 是不行的,會返回 NaN。
4. 在構(gòu)造函數(shù)中實現(xiàn)繼承(經(jīng)典繼承)
在 ES6 之前,apply 是構(gòu)造函數(shù)繼承的一種常見方案。
function Animal(name) {
this.name = name;
}
function Dog(name, breed) {
Animal.apply(this, [name]); // 繼承 Animal 的屬性
this.breed = breed;
}
const dog = new Dog('旺財', '柴犬');
console.log(dog.name); // 旺財
console.log(dog.breed); // 柴犬通過 Animal.apply(this, [name]),將 Animal 構(gòu)造函數(shù)中的屬性“復制”到 Dog 的實例上。
5. 配合 arguments 實現(xiàn)通用封裝
由于 arguments 是一個類數(shù)組對象,很多時候我們需要將其傳遞給另一個函數(shù),而 apply 可以直接幫我們完成這一操作:
function wrapperFunction() {
return targetFunction.apply(this, arguments);
}
這在寫代理、裝飾器函數(shù)(decorator)時尤其有用。
五、深入理解參數(shù)數(shù)組
apply 的第二個參數(shù)必須是一個數(shù)組或類數(shù)組對象(例如 arguments、NodeList、HTMLCollection)。
錯誤示例:
func.apply(thisArg, 'not an array') // ? 報錯:CreateListFromArrayLike called on non-object
正確示例:
func.apply(thisArg, ['a', 'b']) // ? func.apply(thisArg, arguments) // ?
六、ES6 的替代方案:擴展運算符
雖然 apply 非常強大,但在 ES6 之后,... 擴展運算符提供了更優(yōu)雅的替代寫法。
示例:
Math.max(...arr); // 替代 Math.max.apply(null, arr) func(...args); // 替代 func.apply(thisArg, args)
所以,現(xiàn)代開發(fā)中,如果沒有必要改變 this 的話,推薦使用擴展運算符。
七、注意事項與陷阱
1. 嚴格模式下 this 不自動轉(zhuǎn)為對象
在非嚴格模式中,如果傳入 null 或 undefined,apply 會默認將 this 轉(zhuǎn)為全局對象(瀏覽器中為 window)。
但在嚴格模式中,thisArg 保持原樣:
'use strict';
function test() {
console.log(this); // null
}
test.apply(null);
2. 參數(shù)數(shù)量限制問題
在某些老舊的 JavaScript 引擎中(如 IE),apply 所支持的參數(shù)數(shù)組長度是有限的,如果數(shù)組太大(例如上萬項)可能會報錯。解決辦法是使用循環(huán)或改用 forEach 等方法處理。
八、真實項目中的使用建議
- 在需要動態(tài)傳參時,優(yōu)先考慮
apply或...args。 - 在類數(shù)組轉(zhuǎn)數(shù)組、Math.max/min 操作中,
apply是一種簡單高效的選擇。 - 如果你需要同時控制
this和參數(shù),使用apply或call。 - 在函數(shù)柯里化、裝飾器模式、繼承構(gòu)造函數(shù)中,
apply能帶來極高的復用性。
到此這篇關(guān)于JavaScript apply 方法示例詳解的文章就介紹到這了,更多相關(guān)JavaScript apply 方法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 徹底搞懂JavaScript中的apply和call方法(必看)
- Js apply方法詳解
- Javascript中call,apply,bind方法的詳解與總結(jié)
- JavaScript中apply方法的應(yīng)用技巧小結(jié)
- JS中使用apply方法通過不同數(shù)量的參數(shù)調(diào)用函數(shù)的方法
- JS中改變this指向的方法(call和apply、bind)
- JS中call/apply、arguments、undefined/null方法詳解
- js繼承call()和apply()方法總結(jié)
- javascript中apply和call方法的作用及區(qū)別說明
相關(guān)文章
Bootstrap 網(wǎng)格系統(tǒng)布局詳解
在平面設(shè)計中,網(wǎng)格是一種由一系列用于組織內(nèi)容的相交的直線(垂直的、水平的)組成的結(jié)構(gòu)(通常是二維的)。這篇文章主要介紹了Bootstrap 網(wǎng)格系統(tǒng)布局,需要的朋友可以參考下2017-03-03
JavaScript實現(xiàn)按照指定長度為數(shù)字前面補零輸出的方法
這篇文章主要介紹了JavaScript實現(xiàn)按照指定長度為數(shù)字前面補零輸出的方法,實例分析了javascript操作數(shù)字補零的技巧,需要的朋友可以參考下2015-03-03
JS讀取XML文件數(shù)據(jù)并以table形式顯示數(shù)據(jù)的方法(兼容IE與火狐)
這篇文章主要介紹了JS讀取XML文件數(shù)據(jù)并以table形式顯示數(shù)據(jù)的方法,涉及javascript針對xml節(jié)點操作及HTML表格操作的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下2016-06-06
Bootstrap告警框(alert)實現(xiàn)彈出效果和短暫顯示后上浮消失的示例代碼
這篇文章主要介紹了Bootstrap告警框(alert)實現(xiàn)彈出效果和短暫顯示后上浮消失,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-08-08

