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