摘要:這里就不講述兩者的不同了基本就是兩個函數的參數使用不一致引入了。調用會創建一個與具有相同函數體和作用域的函數,但是在這個新函數中,將永久地被綁定到了的第一個參數,無論這個函數是如何被調用的。
JavaScript的this
在JavaScript中this是一個永恒的話題,正在能夠完全掌握其實不易,本文主要講解下一下幾種情況下的判定:
全局情況下
對象調用下
call、apply、bind方法
dom事件綁定
setTimeout、setInterval
ajax等異步操作
全局window/global一個在模塊或者全局的情況下調用一個方法時【不在使用 "use strict"的情況,否則不會默認將this指向全局】
var x = 9; function test(){ this.x = 6; } test(); alert(x); //輸出6
可以知道,在這種情況下的this一般是window或者node中的global;
對象調用這里可能是方法作為構造函數來使用,那么這個方法中的this會指向這個構造方法的實例,
function test(){ this.x = 1; } var o = new test(); alert(o.x); // 1
可以看到,在一些情況下如果出現了類似的調用寫法的話,this一般指向的就是調用者本身,形如【object.fn()】,這種情況下的fn里面的this一般指向前面調用fn方法的object對象;
call、apply、bind方法apply()和call()是函數對象的一個方法,它的作用是改變函數的調用對象,它的第一個參數就表示改變后的調用這個函數的對象。因此,this指的就是這第一個參數。這里就不講述兩者的不同了【基本就是兩個函數的參數使用不一致】;
var x = 0; function test(){ alert(this.x); } var o={}; o.x = 1; o.m = test; o.m.apply(); //0 o.m.apply(o); //1
ECMAScript 5 引入了 Function.prototype.bind。調用f.bind(someObject)會創建一個與f具有相同函數體和作用域的函數,但是在這個新函數中,this將永久地被綁定到了bind的第一個參數,無論這個函數是如何被調用的。也和call、apply用相同作用;
以上參考了:http://www.ruanyifeng.com/blo...
https://developer.mozilla.org...
在使用js操作dom的時候,很常見的會綁定事件;比如下面的將元素p綁定click事件,然后事件的回調函數中就可以使用this;this指向這個時間的目標元素,也就是綁定事件的具體元素;
function bluify(e){ console.log(this === e.currentTarget); // 總是 true // 當 currentTarget 和 target 是同一個對象是為 true console.log(this === e.target); this.style.backgroundColor = "#A5D9F3"; } // 獲取文檔中的所有元素的列表 var elements = document.getElementsByTagName("p"); // 將bluify作為元素的點擊監聽函數,當元素被點擊時,就會變成藍色 for(var i=0 ; i而在jQuery的使用中我們基本就是使用$(this)來表示事件的目標元素;因為this就是e.target;而把一個dom元素變為jQuery元素就是使用$把他抱起來就好了;
setTimeout、setInterval的this在js中,window實現了WindowOrWorkerGlobalScope這個mixin的所有方法,其中最被經常使用的就是setTimeout、setInterval,因為這是一個異步的過程:
var x = 33; var test = { x: 22, test:function(){ console.log(this.x) }, time:function(){ setTimeout(this.test,1000); } } test.time(); //輸出33,不是22在使用異步的setTimeout、setInterval時候,由于需要等待特定時間之后在進行執行,所以這個就和setTimeout、setInterval的執行有關,在https://zhuanlan.zhihu.com/p/... 和 https://jakearchibald.com/201... 中可以知道,其實就是event loop的概念,所以其實在使用setTimeout、setInterval的時候會出現等待的時長并不是精準的參數中寫入的時間,原因如下:
setTimeout、setInterval會把參數中的函數多帶帶放在macrotask中,這里面是需要執行的event隊列;
當計時到達時,從macrotask提前需要定時執行的函數,等待當前正在執行的事件隊列執行完成【這里還有當前macrotask后面的mairotask】這里的當前正在執行的就是引起計時不準確的原因;
當執行完當前的macrotask+microtask以后,就開始執行定時函數,這個時候由于是新的全局下執行這個函數【這個時候就和本文第一種說的全局下調用function一樣了,this指向window】,所以this會被window覆蓋掉,故而不是在編寫setTimeout時的執行上下文,函數的[[scrope]]時候的this,
具體的macrotask+microtask可以參考https://zhuanlan.zhihu.com/p/... 和 https://jakearchibald.com/201...
故而解決方法如下:
把this重命名保存:self=this;這樣self還是函數[[scrope]]中的this;而不會被window替換
使用bind把this綁定
使用立即執行函數來函數再包一層
this.intervalID = setInterval( (function(self) { //Self-executing func which takes "this" as self return function() { //Return a function in the context of "self" self.retrieve_rate(); //Thing you wanted to run as non-window "this" } })(this), this.INTERVAL //normal interval, "this" scope not impacted here. );ajax中的this在ajax中我們都會非常謹慎的使用this;這個異步操作在this上也是和setTimeout差不多,肯定是會被覆蓋的,但是并不是被window覆蓋,相反而是被XMLHttpRequest對象覆蓋:
{ "url": "demo_test.txt", "type": "GET", "isLocal": false, "global": true, "processData": true, "async": true, "contentType": "application/x-www-form-urlencoded; charset=UTF-8", "accepts": { "*": "*/*", "text": "text/plain", "html": "text/html", "xml": "application/xml, text/xml", "json": "application/json, text/javascript", "script": "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript" }, "contents": { "xml": {}, "html": {}, "json": {}, "script": {} }, "responseFields": { "xml": "responseXML", "text": "responseText", "json": "responseJSON" }, "converters": { "text html": true }, "flatOptions": { "url": true, "context": true }, "jsonp": "callback", "dataTypes": [ "text" ], "crossDomain": false, "hasContent": false }上面是一個ajax中的this的json格式,測試地址:http://www.runoob.com/try/try... 只需要在ajax的回調中打印this【console.log(JSON.stringify(this))】就可以在開發者工具的console中看到this這面目,也就是上面的格式的數據。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/91406.html
摘要:一什么是定時器提供了一些原生方法來實現延時去執行某一段代碼,下面來簡單介紹一下設置一個定時器,在定時器到期后執行一次函數或代碼段定時器延遲后執行的函數延遲后執行的代碼字符串,不推薦使用原理類似延遲的時間單位毫秒,默認值為向延遲函數傳遞而外的 一、什么是定時器 JS提供了一些原生方法來實現延時去執行某一段代碼,下面來簡單介紹一下 setTimeout: 設置一個定時器,在定時器到期后執行...
摘要:閉包閉包是指有權訪問另一個函數作用域中的變量的函數當某個函數被調用時,會創建一個執行環境及相應的作用域鏈。要注意通過第句聲明的這個方法屬于構造函數生成的對象,而不屬于構造函數的變量對象,也就是說,并不存在于作用域鏈中。 看到評論里有仁兄建議我試試箭頭函數,真是受寵若驚,本來寫這篇文章也只是想記錄寫要點給自己日后看的。今天早上看到一篇總結javascript中this的文章JavaScr...
摘要:在中,只有兩種指向,一種是指向當前的封閉作用域,或者是指向當前作用域的外層,的最頂層就是對象。在非嚴格模式下,默認指向全局對象。瀏覽器環境全局函數方法用于在指定的毫秒數后調用函數或計算表達式。它會不停地調用函數,指導被調用或者窗口被關閉。 1:基本概念 this字面意思是當前,當前執行代碼的環境對象或者是上下文。代表著當前方法執行的環境上下文,那么何為環境上下文,通俗的說,誰調用了函數...
摘要:當間隔時間設置較小時,將會導致回調函數堆積。處理可能阻塞的代碼最簡單且最可控的方式就是在回調函數內部使用函數。但是很明顯,由于指定最大值的限制,還會有定時器沒有被清除掉。另外,盡量避免使用函數,從而避免可能導致的回調函數堆積現象。 由于 Javascript 是異步的,因此我們可以通過 setTimeout 和 setInterval 函數來指定特定時間執行代碼。 function ...
摘要:也就是說,這僅僅是計劃在未來某一個時間執行某個任務,并不能保證精確的時間。重復執行問題這個方法執行時僅當沒有該計時器的其他代碼示例時才進行下一輪的執行。這樣的規則就會導致某些間隔會被跳過,同時多個間隔可能比預期時間要短。 寫在前面,最近在準備校招,陸陸續續做一些之前的總結,寫了一個小系列的文章,想借此機會記錄下來,也能以后有個地方能進行查閱,上一篇文章在css基礎總結希望能幫助一下和我...
閱讀 1490·2021-11-22 13:52
閱讀 1308·2021-09-29 09:34
閱讀 2715·2021-09-09 11:40
閱讀 3038·2019-08-30 15:54
閱讀 1265·2019-08-30 15:53
閱讀 979·2019-08-30 11:01
閱讀 1364·2019-08-29 17:22
閱讀 1957·2019-08-26 10:57