摘要:在中,當使用關鍵字調用函數構造函數時,函數構造函數中也有這個概念,但是它不是惟一的規(guī)則,而且常??梢砸脕碜圆煌瑘?zhí)行上下文的不同對象。因此,我們使用調用函數,可以看到這是對象,并且的屬性是正常的。
一直以來,javascript里邊的this都是一個很難理解的東西,之前看的最多的就是阮一峰老師關于this的理解:
http://www.ruanyifeng.com/blo...
http://www.ruanyifeng.com/blo...
今天在留言區(qū)發(fā)現了一國外大神關于this的理解,借助翻譯工具讀了一下原文,相對來說是最好的關于理解this的文章,就翻譯了一下,也算是記錄一下。
JavaScript的一個常用特性是“this”關鍵字,但它也常常是該語言中最令人困惑和誤解的特性之一?!皌his”到底是什么意思?它是如何決定的?
本文試圖澄清這種困惑,并以一種清晰的方式解釋這個問題的答案。
“this”關鍵字對于那些用其他語言編程的人來說并不新鮮,而且它通常引用在通過類的構造函數實例化類時創(chuàng)建的新對象。例如,如果我有一個類Boat(),它有一個方法moveBoat(),當在moveBoat()方法中引用“this”時,我們實際上是在訪問新創(chuàng)建的Boat()對象。
在JavaScript中,當使用“new”關鍵字調用函數構造函數時,函數構造函數中也有這個概念,但是它不是惟一的規(guī)則,而且“this”常??梢砸脕碜圆煌瑘?zhí)行上下文的不同對象。如果您不熟悉JavaScript的執(zhí)行上下文,我建議您閱讀我關于這個主題的另一篇文章(本人注:文章找不到了)。談得夠多了,讓我們來看一些JavaScript例子:
// 全局作用域 foo = "abc"; alert(foo); // abc this.foo = "def"; alert(foo); // def
無論何時在全局上下文中使用關鍵字“this”(而不是在函數中),它總是指向全局對象?,F在讓我們看看函數中“this”的值:
var boat = { size: "normal", boatInfo: function() { alert(this === boat); alert(this.size); } }; boat.boatInfo(); // true, "normal" var bigBoat = { size: "big" }; bigBoat.boatInfo = boat.boatInfo; bigBoat.boatInfo(); // false, "big"
那么上面的“this”是如何確定的呢?我們可以看到一個對象boat,它有一個屬性size和一個方法boatInfo()。在boatInfo()中,如果該對象的值是實際的boat對象,它將發(fā)出警報,并警告該對象的size屬性。因此,我們使用boat.boatInfo()調用函數,可以看到這是boat對象,并且boat的size屬性是正常的。
然后我們創(chuàng)建另一個對象bigBoat,它的size屬性為big。然而,bigBoat對象沒有一個boatInfo()方法,因此我們使用bigBoat從boat復制該方法。boatInfo = boat.boatInfo。現在,當我們調用bigBoat.boatInfo()并輸入函數時,我們看到它不等于boat, size屬性現在是big。為什么會這樣?這個值在boatInfo()中是如何變化的?
您必須意識到的第一件事是,任何函數中的這個值都不是靜態(tài)的,它總是在每次調用函數時確定的,但是在函數實際執(zhí)行之前,它是代碼。函數內部的值實際上是由父作用域提供的,在父作用域中調用函數,更重要的是,函數語法是如何編寫的。
每當調用一個函數時,我們必須查看方括號/圓括號“()”的左邊。如果在括號的左邊我們可以看到一個引用,那么傳遞給函數調用的“this”的值就是該對象所屬的值,否則它就是全局對象。讓我們來看一些例子:
function bar() { alert(this); } bar(); // global - 因為方法bar()在調用時屬于全局對象 var foo = { baz: function() { alert(this); } } foo.baz(); // foo - 因為方法baz()在調用時屬于對象foo
如果到目前為止一切都很清楚,那么上面的代碼顯然是有意義的。通過用兩種不同的方式編寫call / invoke語法,我們可以在同一個函數中更改“this”的值,從而使事情變得更加復雜:
var foo = { baz: function() { alert(this); } } foo.baz(); // foo - 因為baz在調用時屬于foo對象 var anotherBaz = foo.baz; anotherBaz(); // global - 因為方法anotherBaz()在調用時屬于全局對象,而不是foo
在這里,我們看到baz()中的“this”值每次都是不同的,因為它的語法調用有兩種不同的方式?,F在,讓我們看看“this”在深度嵌套對象中的值:
var anum = 0; var foo = { anum: 10, baz: { anum: 20, bar: function() { console.log(this.anum); } } } foo.baz.bar(); // 20 - 因為()的左邊是bar,它在調用時屬于baz對象 var hello = foo.baz.bar; hello(); // 0 - 因為()的左邊是hello,它在調用時屬于全局對象
另一個經常被問到的問題是如何在事件處理程序中確定關鍵字“this”?答案是,事件處理程序中的“this”總是指向它所觸發(fā)的元素。我們來看一個例子:
I am an element with id #testfunction doAlert() { alert(this.innerHTML); } doAlert(); // undefined var myElem = document.getElementById("test"); myElem.onclick = doAlert; alert(myElem.onclick === doAlert); // true myElem.onclick(); // I am an element
這里我們可以看到,當第一次調用doAlert()時,它會發(fā)出未定義的警報,因為doAlert()屬于全局對象。然后我們寫myElem。onclick = doAlert,它將函數doAlert()復制到myElem的onclick()事件。這基本上意味著無論何時觸發(fā)onclick(),它都是myElem的一個方法,這意味著“This”的值就是myElem對象。
關于這個主題,我想指出的最后一點是,“this”的值也可以使用call()和apply()手動設置,覆蓋了我們今天討論的內容。同樣有趣的是,當在函數構造函數中調用“this”時,“this”引用構造函數中所有實例中新創(chuàng)建的對象。原因是函數構造函數是用“new”關鍵字調用的,它創(chuàng)建了一個新對象,其中構造函數中的“this”總是引用剛剛創(chuàng)建的新對象。
總結
希望今天的博客文章已經澄清了對“this”這個關鍵字的任何誤解,你可以一直知道“this”的正確值。我們現在知道,“this”的值從來不是靜態(tài)的,它的值取決于函數是如何調用的。
原文:http://davidshariff.com/blog/...
歡迎關注小程序,感謝您的支持!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://m.hztianpu.com/yun/103818.html
摘要:原理是類的構造函數被調用,并且實例化了新的對象。盡管的語法非常相同,但使用在底層還是會引發(fā)不同行為沒有構造函數首先,我們并不是必須要用一個類來生成對象。構造函數只不過是在調用時關鍵字放在其前面的普通方法而已。 由于存在海量的庫和工具,以及各種各樣簡化你開發(fā)的玩意兒,很多程序員開始在不深入了解底層的情況下開發(fā)應用。JavaScript就是這種現象的代言人。JavaScript作為一種最復...
摘要:主題來自于的典型面試問題列表。有多種方法來處理事件委托。這種方法的缺點是父容器的偵聽器可能需要檢查事件來選擇正確的操作,而元素本身不會是一個監(jiān)聽器。 showImg(http://fw008950-flywheel.netdna-ssl.com/wp-content/uploads/2014/11/Get-Hired-Fast-How-to-Job-Search-Classifieds...
摘要:所以是在一秒后顯示的。這個行為不會耗費資源,因為引擎可以同時處理其他任務執(zhí)行其他腳本,處理事件等。每個回調首先被放入微任務隊列然后在當前代碼執(zhí)行完成后被執(zhí)行。,函數是異步的,但是會立即運行。否則,就返回結果,并賦值。 「async/await」是 promises 的另一種更便捷更流行的寫法,同時它也更易于理解和使用。 Async functions 讓我們以 async 這個關鍵字開...
摘要:關鍵字會實例化一個新的對象實例,并在執(zhí)行構造函數時將指向該實例。原文鏈接譯是什么對象的內部工作原理 原文鏈接:What is this? The Inner Workings of JavaScript Objects (需要梯子) 原文作者:Eric Elliott 譯文永久鏈接:【譯】什么是 this?JavaScript 對象的內部工作原理 譯者:士心 翻譯目的:函數動...
摘要:原文鏈接原文作者你想知道的關于作用域的一切譯中有許多章節(jié)是關于的但是對于初學者來說甚至是一些有經驗的開發(fā)者這些有關作用域的章節(jié)既不直接也不容易理解這篇文章的目的就是為了幫助那些想更深一步學習了解作用域的開發(fā)者尤其是當他們聽到一些關于作用域的 原文鏈接: Everything you wanted to know about JavaScript scope原文作者: Todd Mott...
閱讀 3761·2021-11-23 09:51
閱讀 2066·2021-11-16 11:42
閱讀 3380·2021-11-08 13:20
閱讀 1169·2019-08-30 15:55
閱讀 2266·2019-08-30 10:59
閱讀 1315·2019-08-29 14:04
閱讀 1128·2019-08-29 12:41
閱讀 2255·2019-08-26 12:22