摘要:和的基本作用改變對象的執(zhí)行上下文改變什么是執(zhí)行上下文我們在寫一個方法的時候,總是會用到一個關(guān)鍵字,而的指向就是我們這里所說的執(zhí)行上下文執(zhí)行環(huán)境,首先,指向的永遠是調(diào)用該方法的對象,如何證明的指向就是當前對象呢看下面這段代碼代碼中方法執(zhí)行
【call() 和 apply() 的基本作用】 改變對象的執(zhí)行上下文--改變(this)
什么是執(zhí)行上下文? 我們在寫一個方法的時候,總是會用到一個關(guān)鍵字this,而this的指向就是我們這里所說的執(zhí)行上下文(執(zhí)行環(huán)境),
首先,this指向的永遠是調(diào)用該方法的對象,如何證明this的指向就是當前對象呢?看下面這段代碼:
function func () { this.a = 1; console.log(this.a); } func(); // 1
代碼中方法執(zhí)行后控制臺輸出1,由于func是全局對象window下的一個方法,那么調(diào)用該方法的對象就應(yīng)該是全局對象window,所以this理論上指向的對象就應(yīng)該是window
如果理論成立,而this.a==1,也就是說變量a是一個全局變量。在控制臺上直接輸入a或window.a后回車,會發(fā)現(xiàn)輸出了1,所以在func這個方法中,this的指向就是window
換個方式來驗證下:
var person = { name: "xiao ming", age: 18, who: function () { console.log( "my name is " + this.name + " , " + this.age + " years old" ); console.log( person === this); } } person.who(); // my name is xiao ming , 18 years old // true
上面這段代碼中who方法是person對象的一個屬性,被person對象調(diào)用,所以this的指向也就是person
那么在知道什么是執(zhí)行上下文以后,就可以比較好的理解改變執(zhí)行上下文的含義了,舉個不恰當?shù)睦踝樱?/p>
小明有一個炒菜的鏟子,小明的室友小剛今天突然想自己做菜吃,但是小剛沒有鏟子。小剛又不想為了做個菜多帶帶買把鏟子,于是就借用了小明的鏟子,這樣既達到了目的,又節(jié)省了開支,一舉兩得
改變執(zhí)行上下文也是一樣,A對象有一個方法,而B對象因為某種不可言說的情況也需要用到一樣的方法,那么這時候我們是多帶帶為B擴展個方法呢,還是借用一下A的方法呢?當然是借用A的啦,既完成了需求,又減少了內(nèi)存的占用
【call()與apply()異同】 基本使用call()
function.call(obj[,arg1[, arg2[, [,.argN]]]]])
調(diào)用call的對象必須是個函數(shù)function,call的第一個參數(shù)將會是function改變上下文后指向的對象,也就是上面例子里的小剛,如果不傳,將會默認是全局對象window,第二個參數(shù)開始可以接收任意個參數(shù),這些參數(shù)將會作為function的參數(shù)傳入function,調(diào)用call的方法會立即執(zhí)行
apply()
function.apply(obj[,argArray])
與call方法的使用基本一致,但是只接收兩個參數(shù),其中第二個參數(shù)必須是一個數(shù)組或者類數(shù)組,這也是這兩個方法很重要的一個區(qū)別
異同相同點
都能夠改變方法的執(zhí)行上下文(執(zhí)行環(huán)境),將一個對象的方法交給另一個對象來執(zhí)行,并且是立即執(zhí)行
不同點
call方法從第二個參數(shù)開始可以接收任意個參數(shù),每個參數(shù)會映射到相應(yīng)位置的func的參數(shù)上,可以通過參數(shù)名調(diào)用,但是如果將所有的參數(shù)作為數(shù)組傳入,它們會作為一個整體映射到func對應(yīng)的第一個參數(shù)上,之后參數(shù)都為空
function func (a,b,c) {} func.call(obj, 1,2,3) // function接收到的參數(shù)實際上是 1,2,3 func.call(obj, [1,2,3]) // function接收到的參數(shù)實際上是 [1,2,3],undefined,undefined
apply方法最多只有兩個參數(shù),第二個參數(shù)接收數(shù)組或者類數(shù)組,但是都會被轉(zhuǎn)換成類數(shù)組傳入func中,并且會被映射到func對應(yīng)的參數(shù)上
func.apply(obj, [1,2,3]) // function接收到的參數(shù)實際上是 1,2,3 func.apply(obj, { 0: 1, 1: 2, 2: 3, length: 3 }) // function接收到的參數(shù)實際上是 1,2,3
兩個方法該如何選擇?
簡單的說,根據(jù)你要傳入的參數(shù)來做選擇,不需要傳參或者只有1個參數(shù)的時候,用apply,當要傳入多個對象時,用call,或者,如果需要傳入的參數(shù)已經(jīng)是一個數(shù)組或者類數(shù)組了,就用apply,如果還是多帶帶的需要逐個傳入的,可以考慮使用call(如果你不嫌麻煩的話 )
【對象繼承】由于可以改變this的指向,所以也就可以實現(xiàn)對象的繼承
function superClass () { this.a = 1; this.print = function () { console.log(this.a); } } function subClass () { superClass.call(this); this.print(); } subClass(); // 1
subClass通過call方法,繼承了superClass的print方法和a變量,同時subClass還可以擴展自己的其他方法
本文借鑒了一些其他小伙伴的栗子,簡單做了歸納總結(jié)及梳理
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/89051.html
摘要:前言接上篇前端筆試題面試題記錄上。默認值,不脫離文檔流,,,,等屬性不生效。。不脫離文檔流,依據(jù)自身位置進行偏離,當子元素設(shè)置,將依據(jù)它進行偏離。。 前言 接上篇前端筆試題面試題記錄(上)。趁清明小長假,把上篇剩下的部分也寫一下,因為最近比較忙這篇已經(jīng)拖了很久了?,F(xiàn)在剛剛開始銀四了,應(yīng)該還是有些小伙伴在找工作,時間還不算太晚,希望本篇可以幫到這些小伙伴。 個人博客了解一下:obkoro...
摘要:前言接上篇前端筆試題面試題記錄上。默認值,不脫離文檔流,,,,等屬性不生效。。不脫離文檔流,依據(jù)自身位置進行偏離,當子元素設(shè)置,將依據(jù)它進行偏離。。 前言 接上篇前端筆試題面試題記錄(上)。趁清明小長假,把上篇剩下的部分也寫一下,因為最近比較忙這篇已經(jīng)拖了很久了?,F(xiàn)在剛剛開始銀四了,應(yīng)該還是有些小伙伴在找工作,時間還不算太晚,希望本篇可以幫到這些小伙伴。 個人博客了解一下:obkoro...
摘要:函數(shù)被轉(zhuǎn)化之后得到柯里化函數(shù),能夠處理的所有剩余參數(shù)。因此柯里化也被稱為部分求值。那么函數(shù)的柯里化函數(shù)則可以如下因此下面的運算方式是等價的。而這里對于函數(shù)參數(shù)的自由處理,正是柯里化的核心所在。額外知識補充無限參數(shù)的柯里化。 showImg(https://segmentfault.com/img/remote/1460000008493346); 柯里化是函數(shù)的一個比較高級的應(yīng)用,想要...
摘要:前言在阿里和騰訊工作了年,當了年的前端面試官,把期間我和我的同事常問的面試題和答案匯總在我的中。項目地址是我是小蝌蚪,騰訊高級前端工程師,跟著我一起每周攻克幾個前端技術(shù)難點。 前言 在阿里和騰訊工作了6年,當了3年的前端面試官,把期間我和我的同事常問的面試題和答案匯總在我 Github 的 Weekly-FE-Interview 中。希望對大家有所幫助。 如果你在bat面試的時候遇到了...
閱讀 3728·2021-10-11 10:59
閱讀 1317·2019-08-30 15:44
閱讀 3489·2019-08-29 16:39
閱讀 2896·2019-08-29 16:29
閱讀 1812·2019-08-29 15:24
閱讀 817·2019-08-29 15:05
閱讀 1271·2019-08-29 12:34
閱讀 2350·2019-08-29 12:19