摘要:這里就不講述兩者的不同了基本就是兩個函數(shù)的參數(shù)使用不一致引入了。調(diào)用會創(chuàng)建一個與具有相同函數(shù)體和作用域的函數(shù),但是在這個新函數(shù)中,將永久地被綁定到了的第一個參數(shù),無論這個函數(shù)是如何被調(diào)用的。
JavaScript的this
在JavaScript中this是一個永恒的話題,正在能夠完全掌握其實不易,本文主要講解下一下幾種情況下的判定:
全局情況下
對象調(diào)用下
call、apply、bind方法
dom事件綁定
setTimeout、setInterval
ajax等異步操作
全局window/global一個在模塊或者全局的情況下調(diào)用一個方法時【不在使用 "use strict"的情況,否則不會默認(rèn)將this指向全局】
var x = 9; function test(){ this.x = 6; } test(); alert(x); //輸出6
可以知道,在這種情況下的this一般是window或者node中的global;
對象調(diào)用這里可能是方法作為構(gòu)造函數(shù)來使用,那么這個方法中的this會指向這個構(gòu)造方法的實例,
function test(){ this.x = 1; } var o = new test(); alert(o.x); // 1
可以看到,在一些情況下如果出現(xiàn)了類似的調(diào)用寫法的話,this一般指向的就是調(diào)用者本身,形如【object.fn()】,這種情況下的fn里面的this一般指向前面調(diào)用fn方法的object對象;
call、apply、bind方法apply()和call()是函數(shù)對象的一個方法,它的作用是改變函數(shù)的調(diào)用對象,它的第一個參數(shù)就表示改變后的調(diào)用這個函數(shù)的對象。因此,this指的就是這第一個參數(shù)。這里就不講述兩者的不同了【基本就是兩個函數(shù)的參數(shù)使用不一致】;
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。調(diào)用f.bind(someObject)會創(chuàng)建一個與f具有相同函數(shù)體和作用域的函數(shù),但是在這個新函數(shù)中,this將永久地被綁定到了bind的第一個參數(shù),無論這個函數(shù)是如何被調(diào)用的。也和call、apply用相同作用;
以上參考了:http://www.ruanyifeng.com/blo...
https://developer.mozilla.org...
在使用js操作dom的時候,很常見的會綁定事件;比如下面的將元素p綁定click事件,然后事件的回調(diào)函數(shù)中就可以使用this;this指向這個時間的目標(biāo)元素,也就是綁定事件的具體元素;
function bluify(e){ console.log(this === e.currentTarget); // 總是 true // 當(dāng) currentTarget 和 target 是同一個對象是為 true console.log(this === e.target); this.style.backgroundColor = "#A5D9F3"; } // 獲取文檔中的所有元素的列表 var elements = document.getElementsByTagName("p"); // 將bluify作為元素的點擊監(jiān)聽函數(shù),當(dāng)元素被點擊時,就會變成藍(lán)色 for(var i=0 ; i而在jQuery的使用中我們基本就是使用$(this)來表示事件的目標(biāo)元素;因為this就是e.target;而把一個dom元素變?yōu)閖Query元素就是使用$把他抱起來就好了;
setTimeout、setInterval的this在js中,window實現(xiàn)了WindowOrWorkerGlobalScope這個mixin的所有方法,其中最被經(jīng)常使用的就是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時候,由于需要等待特定時間之后在進(jìn)行執(zhí)行,所以這個就和setTimeout、setInterval的執(zhí)行有關(guān),在https://zhuanlan.zhihu.com/p/... 和 https://jakearchibald.com/201... 中可以知道,其實就是event loop的概念,所以其實在使用setTimeout、setInterval的時候會出現(xiàn)等待的時長并不是精準(zhǔn)的參數(shù)中寫入的時間,原因如下:
setTimeout、setInterval會把參數(shù)中的函數(shù)多帶帶放在macrotask中,這里面是需要執(zhí)行的event隊列;
當(dāng)計時到達(dá)時,從macrotask提前需要定時執(zhí)行的函數(shù),等待當(dāng)前正在執(zhí)行的事件隊列執(zhí)行完成【這里還有當(dāng)前macrotask后面的mairotask】這里的當(dāng)前正在執(zhí)行的就是引起計時不準(zhǔn)確的原因;
當(dāng)執(zhí)行完當(dāng)前的macrotask+microtask以后,就開始執(zhí)行定時函數(shù),這個時候由于是新的全局下執(zhí)行這個函數(shù)【這個時候就和本文第一種說的全局下調(diào)用function一樣了,this指向window】,所以this會被window覆蓋掉,故而不是在編寫setTimeout時的執(zhí)行上下文,函數(shù)的[[scrope]]時候的this,
具體的macrotask+microtask可以參考https://zhuanlan.zhihu.com/p/... 和 https://jakearchibald.com/201...
故而解決方法如下:
把this重命名保存:self=this;這樣self還是函數(shù)[[scrope]]中的this;而不會被window替換
使用bind把this綁定
使用立即執(zhí)行函數(shù)來函數(shù)再包一層
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中我們都會非常謹(jǐn)慎的使用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的回調(diào)中打印this【console.log(JSON.stringify(this))】就可以在開發(fā)者工具的console中看到this這面目,也就是上面的格式的數(shù)據(jù)。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/91406.html
摘要:一什么是定時器提供了一些原生方法來實現(xiàn)延時去執(zhí)行某一段代碼,下面來簡單介紹一下設(shè)置一個定時器,在定時器到期后執(zhí)行一次函數(shù)或代碼段定時器延遲后執(zhí)行的函數(shù)延遲后執(zhí)行的代碼字符串,不推薦使用原理類似延遲的時間單位毫秒,默認(rèn)值為向延遲函數(shù)傳遞而外的 一、什么是定時器 JS提供了一些原生方法來實現(xiàn)延時去執(zhí)行某一段代碼,下面來簡單介紹一下 setTimeout: 設(shè)置一個定時器,在定時器到期后執(zhí)行...
摘要:閉包閉包是指有權(quán)訪問另一個函數(shù)作用域中的變量的函數(shù)當(dāng)某個函數(shù)被調(diào)用時,會創(chuàng)建一個執(zhí)行環(huán)境及相應(yīng)的作用域鏈。要注意通過第句聲明的這個方法屬于構(gòu)造函數(shù)生成的對象,而不屬于構(gòu)造函數(shù)的變量對象,也就是說,并不存在于作用域鏈中。 看到評論里有仁兄建議我試試箭頭函數(shù),真是受寵若驚,本來寫這篇文章也只是想記錄寫要點給自己日后看的。今天早上看到一篇總結(jié)javascript中this的文章JavaScr...
摘要:在中,只有兩種指向,一種是指向當(dāng)前的封閉作用域,或者是指向當(dāng)前作用域的外層,的最頂層就是對象。在非嚴(yán)格模式下,默認(rèn)指向全局對象。瀏覽器環(huán)境全局函數(shù)方法用于在指定的毫秒數(shù)后調(diào)用函數(shù)或計算表達(dá)式。它會不停地調(diào)用函數(shù),指導(dǎo)被調(diào)用或者窗口被關(guān)閉。 1:基本概念 this字面意思是當(dāng)前,當(dāng)前執(zhí)行代碼的環(huán)境對象或者是上下文。代表著當(dāng)前方法執(zhí)行的環(huán)境上下文,那么何為環(huán)境上下文,通俗的說,誰調(diào)用了函數(shù)...
摘要:當(dāng)間隔時間設(shè)置較小時,將會導(dǎo)致回調(diào)函數(shù)堆積。處理可能阻塞的代碼最簡單且最可控的方式就是在回調(diào)函數(shù)內(nèi)部使用函數(shù)。但是很明顯,由于指定最大值的限制,還會有定時器沒有被清除掉。另外,盡量避免使用函數(shù),從而避免可能導(dǎo)致的回調(diào)函數(shù)堆積現(xiàn)象。 由于 Javascript 是異步的,因此我們可以通過 setTimeout 和 setInterval 函數(shù)來指定特定時間執(zhí)行代碼。 function ...
摘要:也就是說,這僅僅是計劃在未來某一個時間執(zhí)行某個任務(wù),并不能保證精確的時間。重復(fù)執(zhí)行問題這個方法執(zhí)行時僅當(dāng)沒有該計時器的其他代碼示例時才進(jìn)行下一輪的執(zhí)行。這樣的規(guī)則就會導(dǎo)致某些間隔會被跳過,同時多個間隔可能比預(yù)期時間要短。 寫在前面,最近在準(zhǔn)備校招,陸陸續(xù)續(xù)做一些之前的總結(jié),寫了一個小系列的文章,想借此機(jī)會記錄下來,也能以后有個地方能進(jìn)行查閱,上一篇文章在css基礎(chǔ)總結(jié)希望能幫助一下和我...
閱讀 1459·2021-11-22 13:52
閱讀 1281·2021-09-29 09:34
閱讀 2690·2021-09-09 11:40
閱讀 3031·2019-08-30 15:54
閱讀 1255·2019-08-30 15:53
閱讀 971·2019-08-30 11:01
閱讀 1354·2019-08-29 17:22
閱讀 1943·2019-08-26 10:57