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