javascript
理解JavaScript中this的指向详解
?
this的定義和理解:
this是JavaScript語言的一個(gè)關(guān)鍵字,它是函數(shù)運(yùn)行時(shí),在函數(shù)體內(nèi)部自動生成的一個(gè)對象,只能在函數(shù)體內(nèi)使用。
?
1、this和執(zhí)行環(huán)境對象有關(guān),和函數(shù)的聲明無關(guān)。
var name="Tom";var Bob={name:'Bob',show:function(){console.log(this.name);}};var show=Bob.show; //等同于var show=function(){console.log(this.name);}show(); //輸出的是Tom,全局對象調(diào)用show()函數(shù)window.Bob.show(); //輸出是 Bob ,函數(shù)執(zhí)行對象是Bobvar someone={name:"蓋倫",say:function(){console.log(this.name);}};var otherone={name:"杰克",speak:someone.say //等同于聲明函數(shù)speak:function(){console.log(this.name);}};otherone.speak(); //輸出 杰克 ,函數(shù)被執(zhí)行時(shí)this指向調(diào)用的對象otherone上述代碼解析:函數(shù)執(zhí)行時(shí),this指向的是函數(shù)運(yùn)行時(shí)所在的當(dāng)前環(huán)境對象。注意this和執(zhí)行環(huán)境有關(guān),和函數(shù)的聲明無關(guān)。。也可以理解為this指向的是調(diào)用它的對象!
?
2、函數(shù)沒有明確的執(zhí)行對象時(shí),this指向全局對象window。
var a=11;function test1(){var person="zhangsan";console.log(this); //輸出全局對象windowconsole.log(this.person); //undefinedconsole.log(this.a); // 11}test1(); //沒有明確函數(shù)執(zhí)行對象時(shí),this指向window全局對象window.test1(); //作用同上var name="Jack";var Rose={name:'rose',showName:function(){console.log(this.name);}};var Jane={name:'Jane',showName:function(){var fun=Rose.showName; //等同于var fun=function(){console.log(this.name);}fun(); //在Jane.showName聲明時(shí)執(zhí)行了,沒有明確的執(zhí)行對象,this指向全局對象window}};Jane.showName();var obj = {a:10,b:{a:12,fn:function(){console.log(this.a); //undefinedconsole.log(this); //window}}}var j = obj.b.fn; //等同于 j=function(){console.log(this.a);console.log(this);} j(); //所以this指向window, this.a是undefined上述代碼解析:沒有明確的執(zhí)行對象時(shí),this指向全局對象window。瀏覽器中window是js中的全局對象,創(chuàng)建的對象和聲明的函數(shù)實(shí)際是在給window添加屬性;
?
3、定時(shí)器setTimeout 、setInterval 和匿名函數(shù)執(zhí)行時(shí)的當(dāng)前對象是全局對象window,定時(shí)器也可以理解為延遲執(zhí)行的匿名函數(shù)
var name="Jack";var nameObj={name:'rose',showName:function(){console.log(this.name);},waitShowName:function(){setTimeout(this.showName,5000); //等同于延遲執(zhí)行function(){...}(this.showName)的匿名函數(shù)}};nameObj.waitShowName(); //輸出 Jack ,定時(shí)器和匿名函數(shù)執(zhí)行的當(dāng)前對象是window全局對象(function(val){if(val>10){console.log(this); //輸出window}})(55);如何使定時(shí)器中的執(zhí)行對象不是window對象,可以通過var that=this; 的形式保存定時(shí)器所在函數(shù)的對象,定時(shí)器中匿名函數(shù)使用that獲取定時(shí)器所在的對象
var name = "Bob"; var nameObj ={ name : "Tom", showName : function(){ alert(this.name); }, waitShowName : function(){var that = this; //保存調(diào)用waitShowName()函數(shù)時(shí)的對象到that//定時(shí)器使用時(shí),使用that也就是定時(shí)器所在對象nameObj,而不是windowsetTimeout(function(){that.showName();}, 1000);} }; nameObj.waitShowName(); //Tom4、構(gòu)造函數(shù)使用new關(guān)鍵詞創(chuàng)建對象后,構(gòu)造函數(shù)中的this指向該構(gòu)造函數(shù)創(chuàng)建出來的新對象
function Person(val){this.name=val}Person.prototype.show=function(){console.log(this.name);};var zhangsan=new Person("zhangsan"); //new關(guān)鍵詞會根據(jù)構(gòu)造函數(shù)創(chuàng)建一個(gè)新對象,this指向新對象zhangsan.show();如果構(gòu)造函數(shù)中使用return 返回一個(gè)對象,new 關(guān)鍵詞創(chuàng)建的新對象會被return返回的對象替換,return返回的是非對象時(shí)this指向new創(chuàng)建的新對象,如下
function fn(){ this.name = 'Tom'; return {name:'xiaohong',showName:function(){console.log(this.name);}}; } var a = new fn; a.showName(); //輸出 xiaohongfunction fn(){ this.name = 'Tom'; return false; //return 返回非對象 } var a = new fn; console.log(a.name); //輸出 Tom?
5、eval() 函數(shù) 和 new Function() 使用字符串作為執(zhí)行的代碼體
eval() 函數(shù)計(jì)算 JavaScript 字符串,并把它作為腳本代碼來執(zhí)行。如果參數(shù)是一個(gè)表達(dá)式,eval() 函數(shù)將執(zhí)行表達(dá)式。如果參數(shù)是Javascript語句,eval()將執(zhí)行 Javascript 語句。
var a=eval('2+8'); //eval函數(shù)使用string作為參數(shù),可以計(jì)算表達(dá)式或者執(zhí)行js語句var b=eval('console.log("這是使用eval函數(shù)直接執(zhí)行js語句獲取的結(jié)果");');console.log(a);類似 eval()函數(shù),new Function() 可以將字符串當(dāng)做代碼(函數(shù)體)來執(zhí)行。最后一個(gè)string參數(shù)做函數(shù)體,其他參數(shù)做該函數(shù)的參數(shù)
//Function 這個(gè)構(gòu)造函數(shù)可以用來創(chuàng)建函數(shù)對象//一個(gè)參數(shù)都不傳的時(shí)候,創(chuàng)建了一個(gè)fn0的函數(shù)var fn0=new Function();console.log(typeof fn0); //function//這里是創(chuàng)建了一個(gè)fn1的函數(shù),只傳一個(gè)參數(shù)string時(shí),函數(shù)體就是傳入的字符串形式的js語句var fn1=new Function("console.log('666666');"); fn1(); //輸出 666666//傳入多個(gè)參數(shù)的時(shí)候,最后一個(gè)參數(shù)作為函數(shù)體,前面的參數(shù)都作為該函數(shù)的參數(shù)var fn2=new Function("a","b","return a + b;"); console.log(fn2(10,90)); //輸出100?
?
7、call() 和applay() 方法可以改變this指向。這里不細(xì)說,
后續(xù)會有一篇call、applay、bind改變this指向的文章詳細(xì)分析,這里簡單提一下
var name = "window";var someone = {name: "Bob",showName: function(){alert(this.name);} };var other = {name: "Tom" }; someone.showName.apply(); //window someone.showName.apply(other); //Tom ,applay方法使得this指向?yàn)閛ther對象apply和call方法都用于改變函數(shù)執(zhí)行時(shí)的當(dāng)前對象,當(dāng)無參數(shù)時(shí),當(dāng)前對象為window,有參數(shù)時(shí)當(dāng)前對象為該參數(shù)。于是這個(gè)例子Bob成功偷走了Tom的名字;
?
參考網(wǎng)址:http://www.cnblogs.com/justany/archive/2012/11/01/the_keyword_this_in_javascript.html
?
?
?
?
?
總結(jié)
以上是生活随笔為你收集整理的理解JavaScript中this的指向详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: rust(25)-皮尔逊相关系数
- 下一篇: JSON中的JSON.parseArra