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