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

