JS中Function.apply() 的騷操作

wj2015發表於2020-12-21

引自

我的個人部落格,原文連結:JS中Function.apply() 的騷操作

基本介紹

Function.apply()是什麼

apply() 方法是 JS中所有函式預設都有的方法,IE5+支援,如果需要 IE5 的支援的話,可以參考部落格 www.jb51.net/article/44151.htm

都知道,在JS中可以透過 this 關鍵字獲取當前執行環境,比如:

var obj = {
    name: 'Wang',
    init: function(){
        this.name = 'Jeffrey';
    }
};
obj.init()
console.log(obj.name);// 輸出Jeffrey

apply 就可以改變這個上下文環境,比如下邊這個例子就是將 obj1 的執行環境變成了 obj2 的執行環境,執行 obj1 的 init 之後,卻將 obj2 的屬性改變了。

var obj = {
    name: 'Wang',
    init: function(name){
        this.name = name;
    }
};
var obj2 = {};
obj.init.apply(obj2, ['Test'])
console.log(obj2.name);// 輸出 Test

apply() 有兩個引數,第一個引數是上下文環境的物件,第二個引數是函式列表,支援陣列形式傳遞

apply()和call()的區別

call() 方法也可以改變函式執行的上下文環境,但是與 apply() 有一定的區別,注意看以下程式碼:

var obj = {
    name: 'Wang',
    desc: '',
    init: function(name, desc){
        this.name = name;
        this.desc = desc;
    }
};
var obj2 = {};
obj.init.apply(obj2, ['Test', 'Hello World'])
console.log(obj2.name);// 輸出 Test
console.log(obj2.desc);// 輸出 Hello World
obj.init.call(obj2, 'Test2', 'Hello World!')
console.log(obj2.name);// 輸出 Test2
console.log(obj2.desc);// 輸出 Hello World!

apply 傳遞引數的方式是陣列,call 傳遞引數的方式是函式列表

所謂騷操作

騷操作,,就是一般想不到,然後偶爾打程式碼的時候突然靈光一閃,一些騷操作就能達到 簡化程式碼,增加效率等功效。

騷操作:陣列合並

假設現在有『陣列A』(1, 2),還有『陣列B』(3, 4, 5),我們希望把 『陣列B』 的資料追加到 『陣列A』中,瞭解contact 函式的童鞋,可能會寫出這樣的程式碼:

var A = [1, 2];
var B = [3, 4, 5];

A = A.contact(B);
console.log(A);// 輸出 1,2,3,4,5

原理是,contact函式能夠連線多個陣列,在不改變原有陣列的前提下,將所有列表合併在一起作為返回值返回到呼叫方。

所以,在這個過程中,會出現一個臨時『陣列C』,擁有 A+B的長度,對於只想合併 AB 陣列的需求來說,是一種記憶體浪費。

所以,有如下騷操作:

var A = [1, 2];
var B = [3, 4, 5];

A.push.apply(A, B);
console.log(A);// 輸出 1,2,3,4,5

解析:

呼叫A陣列的 push 函式的 apply 函式,將上下文環境設為『陣列A』,引數列表設為 『陣列B』,由於 push 方法支援如下呼叫: puth(item1, item2, item3),所以就將陣列引數轉換為引數列表,從而實現陣列合並。並且,支援IE5+

相同的呼叫原理還可以用於 unshift ,合併 AB 陣列並將 B 陣列的資料放在前邊。

騷操作:求陣列中的最大最小值

JS中提供了 min()max(),他們都支援一個特點:『動態引數』,意思是傳入 min(1,2,3) 會返回1,傳入 max(1,2,3,4,5) 會返回5。

所以衍生瞭如下操作:

var A = [1, 2, 3];
var B = [1, 2, 3, 4, 5];

var ans1 = min.apply(null, A);
var ans2 = max.apply(null, B);
console.log(ans1, ans2);// 輸出 1 5

總結

applycall 均可以改變上下文執行環境,apply 可以動態傳入陣列引數, call 可以按照正常呼叫函式的方式執行函式,各有特點, apply 配合陣列、物件還可以巧妙的玩出各種騷操作,增加效率和樂趣!

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章