3 回答

TA貢獻(xiàn)1817條經(jīng)驗(yàn) 獲得超14個(gè)贊
好吧,它相當(dāng)于'aaa'.toUpperCase.apply('abc')
,如果有幫助的話。
在 JavaScript 中,對(duì)象實(shí)際上只是關(guān)聯(lián)數(shù)組。當(dāng)數(shù)組鍵字符串(在本例中)具有標(biāo)識(shí)符的形式時(shí),點(diǎn)符號(hào)foo.bar
只是一種方便的簡(jiǎn)寫(xiě)方式 - 所有字母加上一些下劃線,以及數(shù)字,只要它不以一個(gè)開(kāi)頭。foo['bar']
bar
因此,當(dāng)您在對(duì)象上調(diào)用方法時(shí),您實(shí)際上只是在查找存儲(chǔ)在數(shù)組槽中的值,該值的鍵是方法名稱。對(duì)于方法,該值是一個(gè)函數(shù)或“閉包”,然后您可以使用()
語(yǔ)法調(diào)用它。
但是對(duì)于方法名稱,對(duì)象本身的槽通常實(shí)際上是空的!這會(huì)導(dǎo)致 Javascript 在所有相同類型的對(duì)象共享的原型對(duì)象上查找它;這就是 JavaScript 基于原型的繼承的工作方式。在您的情況下,字符串'aaa'
實(shí)際上并沒(méi)有在 key 下存儲(chǔ)任何內(nèi)容toUpperCase
,因此 JS 查看 String 原型以找到它。這樣所有的字符串都有一組通用的方法,你可以調(diào)用它們——而不必在程序中的每個(gè)字符串中存儲(chǔ)這些方法的副本。
就其本身而言,'aaa'.toUpperCase
只是另一個(gè)惰性值。它恰好代表一個(gè)函數(shù)(或閉包),但在你做一些事情讓它運(yùn)行之前,它并不比數(shù)字或字符串更活躍。您可以將它傳遞給其他方法調(diào)用,將其存儲(chǔ)在其他變量或?qū)傩灾校瑢?duì)它進(jìn)行任何您想做的事情。
一旦你調(diào)用它,它就會(huì)得到一個(gè)this
調(diào)用者——方法調(diào)用內(nèi)部的值——這取決于調(diào)用與屬性查找相關(guān)的位置。通常,您只需在從對(duì)象中檢索它的同一表達(dá)式中立即調(diào)用方法,在這種情況下,調(diào)用者就是同一個(gè)對(duì)象。這種行為在工作中更像是 JavaScript 語(yǔ)法魔法;foo.bar()
是一種有效的快捷方式foo.bar.apply(foo)
,使您不必重復(fù)對(duì)象表達(dá)式foo
。
如果您復(fù)制該方法并在沒(méi)有顯式對(duì)象引用的情況下調(diào)用它,它將this
從調(diào)用上下文繼承 的值。并且可能會(huì)抱怨引用的對(duì)象不是預(yù)期的類型。
但是方法本身也是對(duì)象,它們有自己的方法,您可以對(duì)它們進(jìn)行調(diào)用,包括一個(gè)apply
可以讓您使用傳入對(duì)象作為調(diào)用者調(diào)用方法的方法。這就是您的代碼所做的 - 通過(guò)查找方法,'aaa'
然后實(shí)際調(diào)用它'abc'
。

TA貢獻(xiàn)1780條經(jīng)驗(yàn) 獲得超4個(gè)贊
首先,它實(shí)際上相當(dāng)于''.toUpperCase.apply('abc')
. 左邊字符串的內(nèi)容toUpperCase
沒(méi)有區(qū)別。這是什么意思?toUpperCase
是 JavaScript 中每個(gè)字符串都可用的函數(shù)。并且apply
是 JavaScript 中每個(gè)函數(shù)都可用的函數(shù)。它可用于更改this
函數(shù)內(nèi)部的值。
所以,如果你這樣拆分你的代碼,你就會(huì)明白發(fā)生了什么:
const upperCase = ''.toUpperCase; upperCase.apply('abc'); // ABC
碰巧 String#toUpperCase 使用this
內(nèi)部的值轉(zhuǎn)換為大寫(xiě)。

TA貢獻(xiàn)1839條經(jīng)驗(yàn) 獲得超15個(gè)贊
從文檔:
所有 String 實(shí)例都繼承自 String.prototype。對(duì) String 原型對(duì)象的更改會(huì)傳播到所有 String 實(shí)例。
所以所有的字符串都繼承了一系列的方法和屬性,并且因?yàn)槟憧梢允褂胐ot或 square來(lái)訪問(wèn)屬性notation。
因此這段代碼:
'aaa'['toUpperCase'].apply('abc'); // ABC
相當(dāng)于:
'aaa'.toUpperCase.apply('abc'); // ABC
也相當(dāng)于:
String.prototype['toUpperCase'].call('Hello')
// or
String.prototype.toUpperCase.call('Hello')
apply并且也是call繼承自Function.prototype并允許在Javascript中執(zhí)行函數(shù)的函數(shù)。
添加回答
舉報(bào)