成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

詳解JavaScript中的this

開發 前端
JavaScript中的this總是讓人迷惑,應該是js眾所周知的坑之一。個人也覺得js中的this不是一個好的設計,由于this晚綁定的特性,它可以是全局對象,當前對象,或者…有人甚至因為坑大而不用this。

JavaScript中的this總是讓人迷惑,應該是js眾所周知的坑之一。個人也覺得js中的this不是一個好的設計,由于this晚綁定的特性,它可以是全局對象,當前對象,或者…有人甚至因為坑大而不用this。

其實如果完全掌握了this的工作原理,自然就不會走進這些坑。來看下以下這些情況中的this分別會指向什么:

1.全局代碼中的this

  1. alert(this)//window 

全局范圍內的this將會指向全局對象,在瀏覽器中即使window。

2.作為單純的函數調用

  1. function fooCoder(x) {  
  2.     this.x = x;  
  3. }  
  4. fooCoder(2);  
  5. alert(x);// 全局變量x值為2 

這里this指向了全局對象,即window。在嚴格模式中,則是undefined。

3.作為對象的方法調用

  1. var name = "clever coder";  
  2. var person = {  
  3.     name : "foocoder",  
  4.     hello : function(sth){  
  5.         console.log(this.name + " says " + sth);  
  6.     }  
  7. }  
  8. person.hello("hello world"); 

輸出 foocoder says hello world。this指向person對象,即當前對象。

4.作為構造函數

  1. new FooCoder();  

函數內部的this指向新創建的對象。

5.內部函數

  1. var name = "clever coder";  
  2. var person = {  
  3.     name : "foocoder",  
  4.     hello : function(sth){  
  5.         var sayhello = function(sth) {  
  6.             console.log(this.name + " says " + sth);  
  7.         };  
  8.         sayhello(sth);  
  9.     }  
  10. }  
  11. person.hello("hello world");//clever coder says hello world  

在內部函數中,this沒有按預想的綁定到外層函數對象上,而是綁定到了全局對象。這里普遍被認為是JavaScript語言的設計錯誤,因為沒有人想讓內部函數中的this指向全局對象。一般的處理方式是將this作為變量保存下來,一般約定為that或者self:

  1. var name = "clever coder";  
  2. var person = {  
  3.     name : "foocoder",  
  4.     hello : function(sth){  
  5.         var that = this;  
  6.         var sayhello = function(sth) {  
  7.             console.log(that.name + " says " + sth);  
  8.         };  
  9.         sayhello(sth);  
  10.     }  
  11. }  
  12. person.hello("hello world");//foocoder says hello world 

6.使用call和apply設置this

  1. person.hello.call(person, "world"); 

apply和call類似,只是后面的參數是通過一個數組傳入,而不是分開傳入。兩者的方法定義:

  1. call( thisArg [,arg1,arg2,… ] );  // 參數列表,arg1,arg2,...  
  2. apply(thisArg [,argArray] );     // 參數數組,argArray 

兩者都是將某個函數綁定到某個具體對象上使用,自然此時的this會被顯式的設置為第一個參數。

簡單地總結

簡單地總結以上幾點,可以發現,其實只有第六點是讓人疑惑的。

其實就可以總結為以下幾點:

1.當函數作為對象的方法調用時,this指向該對象。

2.當函數作為淡出函數調用時,this指向全局對象(嚴格模式時,為undefined)

3.構造函數中的this指向新創建的對象

4.嵌套函數中的this不會繼承上層函數的this,如果需要,可以用一個變量保存上層函數的this。

再總結的簡單點,如果在函數中使用了this,只有在該函數直接被某對象調用時,該this才指向該對象。

  1. obj.foocoder();  
  2. foocoder.call(obj, ...);  
  3. foocoder.apply(obj, …);  

更進一步

我們可能經常會寫這樣的代碼:

  1. $("#some-ele").click = obj.handler;  

如果在handler中用了this,this會綁定在obj上么?顯然不是,賦值以后,函數是在回調中執行的,this會綁定到$(“#some-div”)元素上。這就需要理解函數的執行環境。本文不打算長篇贅述函數的執行環境,可以參考《javascript高級程序設計》中對執行環境和作用域鏈的相關介紹。這里要指出的時,理解js函數的執行環境,會更好地理解this。

那我們如何能解決回調函數綁定的問題?ES5中引入了一個新的方法,bind():

  1. fun.bind(thisArg[, arg1[, arg2[, ...]]])  
  2.  
  3. thisArg  
  4. 當綁定函數被調用時,該參數會作為原函數運行時的this指向.當使用new 操作符調用綁定函數時,該參數無效.  
  5. arg1, arg2, ...  
  6. 當綁定函數被調用時,這些參數加上綁定函數本身的參數會按照順序作為原函數運行時的參數. 

該方法創建一個新函數,稱為綁定函數,綁定函數會以創建它時傳入bind方法的第一個參數作為this,傳入bind方法的第二個以及以后的參數加上綁定函數運行時本身的參數按照順序作為原函數的參數來調用原函數.

顯然bind方法可以很好地解決上述問題。

  1. $("#some-ele").click(person.hello.bind(person));  
  2. //相應元素被點擊時,輸出foocoder says hello world  

其實該方法也很容易模擬,我們看下Prototype.js中bind方法的源碼:

  1. Function.prototype.bind = function(){  
  2.   var fn = this, args = Array.prototype.slice.call(arguments), object = args.shift();  
  3.   return function(){  
  4.     return fn.apply(object,  
  5.       args.concat(Array.prototype.slice.call(arguments)));  
  6.   };  
  7. };  

明白了么?

相信看完全文以后,this不再是坑~

原文鏈接:http://foocoder.com/blog/xiang-jie-javascriptzhong-de-this.html/

責任編輯:林師授 來源: foocoder
相關推薦

2017-03-20 14:45:42

JavaScript詳解

2009-09-21 16:59:29

Array擴展

2016-10-11 20:33:17

JavaScriptThisWeb

2016-12-27 10:19:42

JavaScriptindexOf

2010-09-08 15:13:09

Node節點Node屬性

2009-10-26 15:07:12

checkbox樹

2024-04-26 08:27:15

JavaScriptCSSHTML元素

2020-11-18 09:06:02

JavaScript開發技術

2016-08-12 11:04:17

JavaScript物聯網應用

2009-11-06 13:28:19

Javascript框

2010-10-09 09:56:51

JavaScriptObject對象

2015-12-24 10:05:39

JavaScripttypeofinstanceof

2012-02-14 09:45:02

JavaScript

2023-06-28 08:34:02

Bind()函數JavaScript

2009-10-20 14:58:15

Javascript事

2014-12-12 10:13:12

JavaScript

2016-09-07 20:43:36

Javascript異步編程

2009-06-10 22:07:59

JavaScriptdocument對象window對象

2010-06-03 08:55:43

LINQ

2014-01-03 09:13:39

JavaScriptthis
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产福利小视频 | 国产在线aa| 孕妇一级毛片 | 亚洲国产成人精品女人久久久 | 亚洲视频在线播放 | 男人的天堂亚洲 | 久久久久91 | 日韩在线精品 | 美女天堂在线 | 久久免费视频观看 | 污视频在线免费观看 | 久久久久国产精品午夜一区 | 狠狠狠色丁香婷婷综合久久五月 | 欧美高清视频 | 在线免费av观看 | 国产欧美精品一区二区 | 国产婷婷综合 | 91天堂网| аⅴ资源新版在线天堂 | 在线观看中文字幕亚洲 | 久久99久久| 81精品国产乱码久久久久久 | 亚洲三级在线观看 | 国产成人综合一区二区三区 | 国产精品一区二区av | 国产精品欧美日韩 | 午夜影院在线观看视频 | 一区二区三区在线免费观看 | 久在线 | 国产美女免费视频 | 欧美一a一片一级一片 | 在线免费看黄 | 韩国久久精品 | 久草新在线 | 精久久| 精品欧美一区二区三区久久久 | 99日韩| 中文字幕成人网 | 欧美日韩精品免费 | 亚洲精品在线观 | 中文字幕一区二区三区四区五区 |