簡答題
1.apply凉馆、call 有什么作用甫男,什么區(qū)別
- call apply,調(diào)用一個函數(shù)女蜈,傳入函數(shù)執(zhí)行上下文及參數(shù)持舆,語法如下:
fn.call(context,param1,param2,...)
fn.apply(context,paramArray)
相同點(diǎn)有
1.產(chǎn)生的作用和效果相同
2.必須至少有一個參數(shù)
3.第一個參數(shù)必須有而且是一個對象
4.如果沒有提供 context,那么 Global 對象被用作 context伪窖。區(qū)別是傳遞的參數(shù)不同逸寓,call傳入的一個一個的參數(shù),而apply傳入的是一個參數(shù)構(gòu)成的數(shù)組覆山。
1 apply最多只能有兩個參數(shù)竹伸,新this對象和一個數(shù)組 argArray。如果給該方法傳遞多個參數(shù)簇宽,則把參數(shù)都寫進(jìn)這個數(shù)組里面勋篓,即使只有一個參數(shù),也要寫進(jìn)數(shù)組里面晦毙。如果 argArray 不是一個有效的數(shù)組或者不是 arguments 對象生巡,那么將導(dǎo)致一個 TypeError耙蔑。如果沒有提供 argArray 和 thisObj 任何一個參數(shù)见妒,那么 Global 對象將被用作 thisObj, 并且無法被傳遞任何參數(shù)
2 call:則是直接的參數(shù)列表甸陌,主要用在js對象各方法互相調(diào)用的時候须揣,使當(dāng)前this實(shí)例指針保持一致,或在特殊情況下需要改變this指針。如果沒有提供 thisObj 參數(shù)钱豁,那么 Global 對象被用作 thisObj耻卡。下面簡單的demo
function person(name,age){
this.name=name;
this.age=age;
this.money=500;
}
function myFun(money){
//此時函數(shù)內(nèi)的this為全局對象window.money
alert(this.money)
}
var money=100;//window.money
myFun(money);//執(zhí)行結(jié)果調(diào)用的全局變量money,為100.
若使用apply和call也能實(shí)現(xiàn)彈出100的效果
//等同于如下:
myFun.apply(window);//100
myFun.call(window);//100
但是我們要想得到person函數(shù)里的money,則要使用call,apply
//若我想出現(xiàn)person函數(shù)的money牲尺,可以使用apply
myFun.apply(person('李四','20'))//500
myFun.apply(person('李四','20'),[])//500
myFun.call(person('李四','20'))//500原因是此時myFun方法里面的this指向的是person('李四','20')對象卵酪,二不是myFun類(函數(shù))幌蚊,故彈出500.
call,apply其實(shí)質(zhì)就是改變this的作用域,this 默認(rèn)情況下為全局作用域。
apply,this的實(shí)例和技巧溃卡,可以看看這篇文章
apply()用法和call()的區(qū)別
代碼題
1.以下代碼輸出什么?
var john = {
firstName: "John"
}
function func() {
console.log(this.firstName + ": hi!")
}
john.sayHi = func
john.sayHi()
結(jié)果輸出:"John: hi!",分析如下:
john.sayHi = func
//使John對象變?yōu)榱? var john= {
firstName:'John',
sayHi:func
}
//這里對象john調(diào)用的func函數(shù)溢豆,這里this就是對象john。
john.sayHi() //輸出結(jié)果為:"John:hi!"
2. 以下代碼的輸出結(jié)果
func() //彈出:[object Window]
function func() {
alert(this)//this默認(rèn)情況下為全局對象window
}
- func函數(shù)是在全局作用域下被調(diào)用的瘸羡,func的this為Window對象
3. 以下代碼的輸出結(jié)果
function fn0(){
function fn(){
console.log(this); //window
}
fn();
}
fn0();
document.addEventListener('click', function(e){
console.log(this); //#Document
setTimeout(function(){
console.log(this); //window
}, 200);
}, false);
- 第一個this輸出結(jié)果為window ,因?yàn)樵诤瘮?shù)被直接調(diào)用時this綁定到全局對象漩仙。在瀏覽器中,window就是該全局對象
- 第二個this輸出結(jié)果為#document犹赖,因?yàn)楹瘮?shù)調(diào)用時this綁定到了document队他。
- 第三個this輸出結(jié)果為window,因?yàn)閟etTimeout,setInterval兩個方法的執(zhí)行上下文與調(diào)用他們的函數(shù)的執(zhí)行上下文是分離的,這兩個方法執(zhí)行的函數(shù)this也是全局對象峻村。
4下面代碼輸出什么麸折,why
var john = {
firstName: "John"
}
function func() {
alert( this.firstName )
}
func.call(john) //輸出結(jié)果為john
- 原因是func.call(john),改變了func函數(shù)執(zhí)行的作用域,使全局的作用域改變?yōu)閖ohn對象的作用域粘昨,此時的this指向?qū)ο骿ohn,所以結(jié)果:this.firstName等同于John.firstName,輸出結(jié)果為John
5下面代碼輸出什么磕谅,why
var john = {
firstName: "John",
surname: "Smith"
}
function func(a, b) {
alert( this[a] + ' ' + this[b] )
}
func.call(john, 'firstName', 'surname') //"John Smith"
- 原因
func.call(john, 'firstName', 'surname')
指定了func函數(shù)在對象john里執(zhí)行,此時傳入的其余兩個參數(shù)代表a和b,此時this.[a] 等同于john.firstName,this.[b]等同于john.surname.
6以下代碼有什么問題雾棺,如何修改
var module= {
bind: function(){
$btn.on('click', function(){
console.log(this) //this指什么,指的是$btn
this.showMsg();
})
},
showMsg: function(){
console.log('饑人谷');
}
}
由于this指向的是$btn,那么接下來執(zhí)行this.showMsg()會報錯膊夹,因?yàn)?btn下沒有showMsg這個方法,它在對象module上捌浩,
-
修改的思路就是讓this指向?qū)ο髆odule,
方法1
//直接使用module調(diào)用
var module= {
bind: function(){
$btn.on('click', function(){
console.log(this) //this指什么,指的是$btn
module.showMsg();
})
},showMsg: function(){ console.log('饑人谷'); } }
方法2
//利用變量儲存當(dāng)前的this的值
var module= {
bind: function(){
var cur=this;
$btn.on('click', function(){
console.log(this) //this指什么,指的是$btn
cur.showMsg();
})
},
showMsg: function(){
console.log('饑人谷');
}
}
7 下面代碼的輸出結(jié)果
var length = 3;
function fa() {
console.log(this.length);
}
var obj = {
length: 2,
doSome: function (fn) {
fn();
arguments[0]();
}
}
obj.doSome(fa)//輸出結(jié)果為3,1
- 當(dāng)執(zhí)行obj.doSome(fa)時放刨,也就變成了執(zhí)行function (fa){fa(); arguments0;} 執(zhí)行函數(shù)內(nèi)部的法fa(),由于fa的執(zhí)行環(huán)境this是window,var length = 3 等同于 window.length =3, 所以彈出結(jié)果為3
- 而當(dāng)執(zhí)行到arguments0時尸饺,執(zhí)行也是調(diào)用fa(),但是調(diào)用的對象是arguments自身进统,此時this.length 等同于 argument.length,由于arguments是一個類數(shù)組對象,只有一個參數(shù)浪听,所以長度為1