2014-07-02 54 views
0

morethanone stackoverflow有關如何在javascript中查找值的數組的最小值或最大值的問題。這不是那個問題。.apply(Math,arrayName)是如何工作的? (javascript)

我想知道爲什麼通過.apply()奇怪的事情,因爲this論點仍然有效。儘管Aaron Crane的a good blog post關於Math對象的API如何變成現實,但仍有一些問題未得到解答。

以下每個代碼片段都適用。我的問題是,如何?到this的任務究竟發生了什麼,這使得每一個工作?

標準建設

var values = [45, 46, 47] 
var min = Math.min.apply(Math, values); 
alert(min); //45 

一個怪異建築,但範圍可能會非常棘手......

var values = [45, 46, 47] 
var min = Math.min.apply(this, values); 
alert(min); //45 

稍微怪異

var values = [45, 46, 47] 
var min = Math.min.apply(global, values); 
alert(min); //45 

怪異儘管如此,但也許好了B/c瀏覽器

var values = [45, 46, 47] 
var min = Math.min.apply(window, values); 
alert(min); //45 

很怪

var values = [45, 46, 47] 
var min = Math.min.apply(null, values); 
alert(min); //45 

真正奇怪的

var values = [45, 46, 47] 
var min = Math.min.apply(undefined, values); 
alert(min); //45 
+2

'Math.min'不以任何方式使用'this',所以它通過它無關緊要,它不關心。 –

+3

作爲'thisArg'傳遞的值只對'function'有影響,如果它依賴於'this'具有特定的值。而且,'Math.min()'[根本不需要引用'this'](http://ecma-international.org/ecma-262/5.1/#sec-15.8.2.12)。 –

+0

「apply」的第一個參數是在函數中應該用作this的值。因爲'Math.min'不會爲任何事情使用'this',所以你通過參數傳遞給'this'在邏輯上無關緊要......你可能會通過''foobar「'或'9/11 '作爲'apply'的第一個參數。 – CBroe

回答

0

TL; DR-Math.min()Math.max()實際上並沒有使用傳遞給它們的參數this,只是讓它們接受參數數組而已,因爲本機API只指定了一個變量列表。 .apply()可以接受參數數組,這就是使用它的原因。

我的猜測是Math作爲this參數傳入,只是爲了清潔。

感謝@Jonathan Lonowski和@Niet the Dark Absol。

2

當使用.apply(),第一個參數控制什麼this指針值將被設置爲功能執行時。在許多情況下,價值至關重要。在少數情況下,this值不在函數實現內部使用(通常被稱爲不對實例數據進行操作的靜態函數)。當不使用this時,this設置爲什麼並不重要,因此.apply()的第一個參數設置爲什麼並不重要。

因此,在特定情況下,Math.min()Math.max()(也可能所有的Math.xxx()功能)不使用this指針在所有的,因爲他們基本上都是不實例數據進行操作的靜態函數。因此,它的設置無關緊要,因此您可以將任何您想要的作爲第一個參數傳遞給Math.min.apply(),並且它不會更改函數調用的結果。


我認爲,人們仍然應該通過正確的值有這將是Math因爲那是當你做一個正常this將是什麼:

Math.min(x, y); 

所以,呈現完全相同的情況使用.apply()Math.min()如上面的代碼,你會做這樣的:

var arr = [x, y]; 
Math.min.apply(Math, arr); 

國際海事組織,這促進適當的習慣和適當的思考什麼第一個論據應該是因爲它會在其他情況下很重要。

僅供參考,類似的問題經常出現在jQuery的$.when.apply($, arr)也沒有使用this說法的實施,使人們可以把它作爲$.when.apply(null, arr)甚至$.when.apply("foo", arr)。就我個人而言,我更願意通過第一個「技術上正確」的論點。

0

apply對第一個參數做了什麼,只是簡單地爲其被調用的函數設置上下文(this)。

因此,可以說,你有一個對象是這樣的:

var obj = { 
    a: 1, 
    b: function() { 
     return this.a; 
    }, 
    c: function() { 
     return 3; 
    } 
} 

如果你打電話obj.b(),你會得到1返回的值,因爲在這種情況下this由前調用bobj定義它(this === obj)。要改變這種狀況,你可以使用apply

obj.b.apply({a:2}); 

這將返回2,因爲你現在是明確地設置this{a:2}

但是:如果你有一個功能,在內部不使用this,比this具有什麼值沒有關係。所以,你可以撥打:

obj.c(); 

或者其中一種:

obj.apply.c(null); 
obj.apply.c(undefined); 
obj.apply.c("xyz"); 

但你總是會得到相同的結果3。這就像設置一個你永遠不會使用的變量。不管它有什麼價值,它都不會影響結果。

顯然,Math.min不使用this,因此在傳遞「無效」上下文時不會中斷。

0

這個(這麼說)是JavaScript的一個棘手的部分。

當你有一個函數時,有一個神奇的變量叫做this。根據你如何調用一個函數,它的上下文設置是不同的。

function myFunction() { 
    return this; 
} 

var myObject = { 
    fn: function() { 
    return this; 
    } 
}; 

myFunction(); // the global object. `window` in browsers, `global` in Node.js 
myFunction.apply(Math); // Math 
myFunction.apply({ hello: "world" }); // { hello: "world" } 

myObject.fn();    // myObject 
myObject.fn.apply(myObject); // myObject 
myObject.fn.apply(Math);  // Math 

的原因,你的例子上述工作是因爲min不使用this可言,這樣你就可以將其分配到任何你想要的。