偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

詳解JavaScript中的this

開(kāi)發(fā) 前端
JavaScript中的this總是讓人迷惑,應(yīng)該是js眾所周知的坑之一。個(gè)人也覺(jué)得js中的this不是一個(gè)好的設(shè)計(jì),由于this晚綁定的特性,它可以是全局對(duì)象,當(dāng)前對(duì)象,或者…有人甚至因?yàn)榭哟蠖挥胻his。

JavaScript中的this總是讓人迷惑,應(yīng)該是js眾所周知的坑之一。個(gè)人也覺(jué)得js中的this不是一個(gè)好的設(shè)計(jì),由于this晚綁定的特性,它可以是全局對(duì)象,當(dāng)前對(duì)象,或者…有人甚至因?yàn)榭哟蠖挥胻his。

其實(shí)如果完全掌握了this的工作原理,自然就不會(huì)走進(jìn)這些坑。來(lái)看下以下這些情況中的this分別會(huì)指向什么:

1.全局代碼中的this

  1. alert(this)//window 

全局范圍內(nèi)的this將會(huì)指向全局對(duì)象,在瀏覽器中即使window。

2.作為單純的函數(shù)調(diào)用

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

這里this指向了全局對(duì)象,即window。在嚴(yán)格模式中,則是undefined。

3.作為對(duì)象的方法調(diào)用

  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對(duì)象,即當(dāng)前對(duì)象。

4.作為構(gòu)造函數(shù)

  1. new FooCoder();  

函數(shù)內(nèi)部的this指向新創(chuàng)建的對(duì)象。

5.內(nèi)部函數(shù)

  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  

在內(nèi)部函數(shù)中,this沒(méi)有按預(yù)想的綁定到外層函數(shù)對(duì)象上,而是綁定到了全局對(duì)象。這里普遍被認(rèn)為是JavaScript語(yǔ)言的設(shè)計(jì)錯(cuò)誤,因?yàn)闆](méi)有人想讓內(nèi)部函數(shù)中的this指向全局對(duì)象。一般的處理方式是將this作為變量保存下來(lái),一般約定為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設(shè)置this

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

apply和call類似,只是后面的參數(shù)是通過(guò)一個(gè)數(shù)組傳入,而不是分開(kāi)傳入。兩者的方法定義:

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

兩者都是將某個(gè)函數(shù)綁定到某個(gè)具體對(duì)象上使用,自然此時(shí)的this會(huì)被顯式的設(shè)置為第一個(gè)參數(shù)。

簡(jiǎn)單地總結(jié)

簡(jiǎn)單地總結(jié)以上幾點(diǎn),可以發(fā)現(xiàn),其實(shí)只有第六點(diǎn)是讓人疑惑的。

其實(shí)就可以總結(jié)為以下幾點(diǎn):

1.當(dāng)函數(shù)作為對(duì)象的方法調(diào)用時(shí),this指向該對(duì)象。

2.當(dāng)函數(shù)作為淡出函數(shù)調(diào)用時(shí),this指向全局對(duì)象(嚴(yán)格模式時(shí),為undefined)

3.構(gòu)造函數(shù)中的this指向新創(chuàng)建的對(duì)象

4.嵌套函數(shù)中的this不會(huì)繼承上層函數(shù)的this,如果需要,可以用一個(gè)變量保存上層函數(shù)的this。

再總結(jié)的簡(jiǎn)單點(diǎn),如果在函數(shù)中使用了this,只有在該函數(shù)直接被某對(duì)象調(diào)用時(shí),該this才指向該對(duì)象。

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

更進(jìn)一步

我們可能經(jīng)常會(huì)寫這樣的代碼:

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

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

那我們?nèi)绾文芙鉀Q回調(diào)函數(shù)綁定的問(wèn)題?ES5中引入了一個(gè)新的方法,bind():

  1. fun.bind(thisArg[, arg1[, arg2[, ...]]])  
  2.  
  3. thisArg  
  4. 當(dāng)綁定函數(shù)被調(diào)用時(shí),該參數(shù)會(huì)作為原函數(shù)運(yùn)行時(shí)的this指向.當(dāng)使用new 操作符調(diào)用綁定函數(shù)時(shí),該參數(shù)無(wú)效.  
  5. arg1, arg2, ...  
  6. 當(dāng)綁定函數(shù)被調(diào)用時(shí),這些參數(shù)加上綁定函數(shù)本身的參數(shù)會(huì)按照順序作為原函數(shù)運(yùn)行時(shí)的參數(shù). 

該方法創(chuàng)建一個(gè)新函數(shù),稱為綁定函數(shù),綁定函數(shù)會(huì)以創(chuàng)建它時(shí)傳入bind方法的第一個(gè)參數(shù)作為this,傳入bind方法的第二個(gè)以及以后的參數(shù)加上綁定函數(shù)運(yùn)行時(shí)本身的參數(shù)按照順序作為原函數(shù)的參數(shù)來(lái)調(diào)用原函數(shù).

顯然bind方法可以很好地解決上述問(wèn)題。

  1. $("#some-ele").click(person.hello.bind(person));  
  2. //相應(yīng)元素被點(diǎn)擊時(shí),輸出foocoder says hello world  

其實(shí)該方法也很容易模擬,我們看下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/

責(zé)任編輯:林師授 來(lái)源: foocoder
相關(guān)推薦

2017-03-20 14:45:42

JavaScript詳解

2009-09-21 16:59:29

Array擴(kuò)展

2016-10-11 20:33:17

JavaScriptThisWeb

2016-12-27 10:19:42

JavaScriptindexOf

2010-09-08 15:13:09

Node節(jié)點(diǎn)Node屬性

2009-10-26 15:07:12

checkbox樹(shù)

2024-04-26 08:27:15

JavaScriptCSSHTML元素

2020-11-18 09:06:02

JavaScript開(kāi)發(fā)技術(shù)

2016-08-12 11:04:17

JavaScript物聯(lián)網(wǎng)應(yīng)用

2009-11-06 13:28:19

Javascript框

2010-10-09 09:56:51

JavaScriptObject對(duì)象

2015-12-24 10:05:39

JavaScripttypeofinstanceof

2012-02-14 09:45:02

JavaScript

2023-06-28 08:34:02

Bind()函數(shù)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對(duì)象window對(duì)象

2010-06-03 08:55:43

LINQ

2014-01-03 09:13:39

JavaScriptthis
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)