一、因?yàn)镴avaScript中的this是在運(yùn)行期綁定的,因此JavaScript中的this關(guān)鍵字具備多重含義。
二、具體在應(yīng)用中,this的指向大概可以分為以下四種。
1.作為對(duì)象的方法調(diào)用? obj.run()
2.作為普通函數(shù)調(diào)用? ? ? function()
3.作為構(gòu)造函數(shù)調(diào)用? ? var b =new a();
4.function.prototype.call或者function.prototype.apply調(diào)用
三、作為對(duì)象的方法調(diào)用和作為普通函數(shù)調(diào)用
window.name=bj;
var obj={
? ? name:zzy,
? ? getName(){
? ? ? ? console.log(this.name)?
? ? ? ? }
}
obj.getNAme();//輸出的zzy
var getA=obj.getName;
getA();? ? ? //輸出的為bj
不管getA之前是getNAme(),還是其他某個(gè)對(duì)象的屬性,只要最后是以getA(),這種方式調(diào)用的,均視為普通函數(shù)調(diào)用,此時(shí)this指向window對(duì)象
但是,在ES5的strict模式下,作為函數(shù)調(diào)用的 this被規(guī)定不會(huì)指向全局對(duì)象
getA();? ? ? //輸出的為underfined
四.構(gòu)造函數(shù)的調(diào)用
通常情況下,構(gòu)造函數(shù)里的this指向那個(gè)返回的這個(gè)對(duì)象,但是如果構(gòu)造器顯示的返回了一個(gè)object類(lèi)型的對(duì)象,則this指向返回的object對(duì)象
var Myclass = function(){
? ? this.name = 'beidan';
}
var obj = new Myclass();?
console.log(obj.name);//beidan
var Myclass = function(){
? ? this.name = 'beidan';
? ? return{? ? ? ? //顯示的返回一個(gè)對(duì)象,注意!既要是顯示,即有return,也要是對(duì)象{}
? ? ? ? name:'test'
? ? }
}
var obj = new Myclass();
console.log(obj.name);//test
五.function.prototype.call或function.prototype.apply調(diào)用
call,apply都是為了改變函數(shù)內(nèi)部this的指向。例如,function.apply()或者
function.apply()都是為了改變函數(shù)內(nèi)部的this指向。
二者的作用完全一樣,只是接受參數(shù)的方式不太一樣。
? ? function.call(this, arg1, arg2);? ? ? ? //參數(shù)列表arg1,arg2
? ? function.apply(this, [arg1, arg2]);? ? //參數(shù)數(shù)組 [arg1,arg2]
第一個(gè)參數(shù),指定了那個(gè)函數(shù)體內(nèi)this對(duì)象的指向,它可以是javascript對(duì)象,如果為null,則函數(shù)體內(nèi)的this會(huì)指向默認(rèn)的window
第二個(gè)參數(shù),call 需要把參數(shù)按順序傳遞進(jìn)去,而 apply 則是把參數(shù)放在數(shù)組里。當(dāng)參數(shù)不確定數(shù)量時(shí)用 apply ,然后把參數(shù) push 進(jìn)數(shù)組傳遞進(jìn)去?;蛘咭部梢酝ㄟ^(guò) arguments來(lái)獲取所有的參數(shù)。這樣看來(lái),apply的使用率更高。
1.修正this指向
在實(shí)際開(kāi)發(fā)過(guò)程中,會(huì)出現(xiàn)一下的情況
document.getElementById('div1').onclick = function(){
? ? console.log(this.id);? //div1
? ? var func = function(){
? ? ? ? console.log(this.id);? ?
? ? }
? ? func();? //通過(guò)普通函數(shù)調(diào)用,this指向window,輸出undefined
}
使用call來(lái)改變this的指向
document.getElementById('div1').onclick = function(){
? ? console.log(this.id);? //div1
? ? var func = function(){
? ? ? ? console.log(this.id);
? ? }
func.call(this);? //使func函數(shù)內(nèi)部的this指向當(dāng)前的函數(shù)對(duì)象,輸出div1
}
2.模擬繼承
function fruits() {}
fruits.prototype = {
? ? color: "red",
? ? say: function() {
? ? ? ? console.log("My color is "+ this.color);
? ? }
}
var apple = new fruits;
apple.say();? ? //My color is red
但是,如果我們還有其它 2個(gè)對(duì)象 banana= {color : "yellow"} ,orange = {color:‘orange’},想使用say方法,但是又不想對(duì)它們重新定義say方法。
那么,我們可以用apply或者call 借用 fruit里面的say方法
banana = {color: "yellow"};
orange = {color:‘orange’};
apple.say.call(banana);? ? //My color is yellow
apple.say.apply(orange );? ? //My color is orange
這里需要注意的是banana繼承apple.say的方法;