問答
apply砰嘁、call 有什么作用,什么區(qū)別峻凫?
在介紹apply和call之前,我們先來看看this览露,
this的指向:this的指向只有函數(shù)調(diào)用的時(shí)候才能確定荧琼。
- 在全局調(diào)用的時(shí)候指向的是window
- 作為對(duì)象的方法調(diào)用的時(shí)候指向的是那個(gè)對(duì)象
- 構(gòu)造函數(shù)的時(shí)候指向的是構(gòu)造出來的對(duì)象
- 在事件的回調(diào)函數(shù)中指的是觸發(fā)事件的DOM節(jié)點(diǎn)(this===e.currentTarget)
- 只用apply和call調(diào)用的時(shí)候指向的是第一個(gè)參數(shù)指定對(duì)象, 如果第一個(gè)null就指向window
如:
<pre>var name = 'hello' var obj = { name: 'world' } function printName() { console.log(this.name) } //全局調(diào)用, 默認(rèn)指向window printName()//輸出'hello' //作為obj的方法調(diào)用, 指向obj obj.printName = printName obj.printName()//輸出'world' //使用call指定this值 printName.call(obj)//輸出'world'
</pre>
作用:兩者都是在指定this值和參數(shù)(參數(shù)以數(shù)組或類數(shù)組對(duì)象的形式存在)的情況下調(diào)用某個(gè)函數(shù)。實(shí)際上就是說用它可以綁定一個(gè)函數(shù)然后在另一個(gè)環(huán)境中(比如另一個(gè)函數(shù)中)使用新環(huán)境給的參數(shù)(指定this值差牛、參數(shù))進(jìn)行運(yùn)算命锄;
區(qū)別:兩者的區(qū)別在于接受的參數(shù)不同,apply接受的是數(shù)組(或者是類數(shù)組對(duì)象)偏化,call接受的是多個(gè)參數(shù)脐恩。
如:
<pre>function sum(a,b){ console.log(a+b) } function applySum(a,b){ return sum.apply(this,[a,b]) //使用apply方法,必須傳入數(shù)組 } function callSum(a,b){ return sum.call(this,a,b)//使用call方法侦讨,逐條列舉參數(shù) } applySum(3,4)//7 //雖然apply接受的是數(shù)組驶冒,但是傳遞給函數(shù)的參數(shù)還是數(shù)組中的元素苟翻,而不是整個(gè)數(shù)組 callSum(3,4)//7
</pre>
由于apply接受數(shù)組類型的參數(shù),所以就有這么個(gè)特別的用法骗污。如:
<pre>var arr =[100,20,300,50] Math.min.apply(null, arr);20//就可以獲得數(shù)組中的最小值 Math.max.apply(null,arr);300//就可以獲得數(shù)組中的最大值
</pre>
代碼
1. 以下代碼輸出什么?
<pre>var john = { firstName: "John" } function func() { alert(this.firstName + ": hi!") } john.sayHi = func john.sayHi()
</pre>
- 輸出 John:hi!
- 調(diào)用對(duì)象john下sayHi方法崇猫,其this指向john
2. 下面代碼輸出什么,為什么需忿?
<pre>`
func()
function func() {
alert(this)
}
`</pre>
- 輸出window诅炉。
- 在全局下調(diào)用func()函數(shù),這里的this指向全局對(duì)象
3. 下面代碼輸出什么屋厘?
<pre>`
function fn0(){
function fn(){
console.log(this);
}
fn();
}
fn0();
document.addEventListener('click', function(e){
console.log(this);
setTimeout(function(){
console.log(this);
}, 200);
}, false);
`</pre>
- fn0()執(zhí)行后輸出window涕烧,此時(shí)的fn0()是在全局環(huán)境下調(diào)用的,this指向window
- 事件綁定后第一次輸出document 汗洒。因?yàn)樵赿ocument上綁定事件议纯,this指document。第二次輸出window仲翎。因?yàn)閟etTimeout,setInterval兩個(gè)方法的執(zhí)行上下文與調(diào)用他們的函數(shù)的執(zhí)行上下文是分離的痹扇,這兩個(gè)方法執(zhí)行的函數(shù)this也是全局對(duì)象。
4. 下面代碼輸出什么溯香,why?
<pre>var john = { firstName: "John" } function func() { alert( this.firstName ) } func.call(john)
</pre>
- 輸出John,當(dāng)函數(shù)被call方法調(diào)用時(shí)浓恶,其this指向傳入的對(duì)象玫坛,這里函數(shù)func的this就指向?qū)ο骿ohn了。
5. 代碼輸出包晰?
<pre>var john = { firstName: "John", surname: "Smith" } function func(a, b) { alert( this[a] + ' ' + this[b] ) } func.call(john, 'firstName', 'surname')
</pre>
- 輸出John Smith湿镀,func.call(context,參數(shù)1,參數(shù)2) 這里函數(shù)執(zhí)行時(shí)傳入的this是john對(duì)象
6. 以下代碼有什么問題,如何修改?
<pre>var module= { bind: function(){ $btn.on('click', function(){ console.log(this) //this指什么 this.showMsg(); }) }, showMsg: function(){ console.log('饑人谷'); } }
</pre>
- this指什么 ?當(dāng)$btn被點(diǎn)擊的時(shí)候, this指向$btn
- this.showMsg(); 執(zhí)行時(shí)報(bào)錯(cuò)伐憾,因?yàn)檫@里的this指向的還是$btn勉痴,而$btn下沒有showMsg()這個(gè)方法,它在對(duì)象module上
修改方法:
<pre>var module= { bind: function(){ $btn.on('click', function(){ console.log(this) module.showMsg(); }) }, showMsg: function(){ console.log('饑人谷'); } }
</pre>
7. 下面代碼輸出什么?
<pre>var length = 3; function fa() { console.log(this.length); } var obj = { length: 2, doSome: function (fn) { fn(); arguments[0](); } } obj.doSome(fa);
</pre>
- 輸出3,1树肃。
- obj.doSome(fa)把fa傳進(jìn)obj的doSome方法的function(fn)內(nèi)蒸矛,并將fn賦值為fa,函數(shù)內(nèi)部的fn()變?yōu)閒a()胸嘴,由于fa函數(shù)是在window下被調(diào)用的雏掠,所以this為window,它的length為3劣像,所以這里輸3乡话。
- 函數(shù)內(nèi)部的arguments為一個(gè)類數(shù)組對(duì)象,這里它內(nèi)部只有一個(gè)值耳奕,即處于數(shù)組0位的function fa()绑青,這里arguments0也是執(zhí)行fa()诬像,但調(diào)用的對(duì)象不同,這里調(diào)用它的是arguments闸婴,this即為arguments坏挠,由于argument只有一個(gè)值,則length為1掠拳,所以這里輸出1癞揉。
版權(quán)歸本人及饑人谷所有,轉(zhuǎn)載請(qǐng)注明出處溺欧。