在JavaScript中this是一個永恆的話題,正在可以徹底掌握其實不易,本文主要講解下一下幾種狀況下的斷定:javascript
一個在模塊或者全局的狀況下調用一個方法時【不在使用 'use strict'的狀況,不然不會默認將this指向全局】php
var x = 9; function test(){ this.x = 6; } test(); alert(x); //輸出6
能夠知道,在這種狀況下的this通常是window或者node中的global;html
這裏多是方法做爲構造函數來使用,那麼這個方法中的this會指向這個構造方法的實例,java
function test(){ this.x = 1; } var o = new test(); alert(o.x); // 1
能夠看到,在一些狀況下若是出現了相似的調用寫法的話,this通常指向的就是調用者自己,形如【object.fn()】,這種狀況下的fn裏面的this通常指向前面調用fn方法的object對象;node
apply()和call()是函數對象的一個方法,它的做用是改變函數的調用對象,它的第一個參數就表示改變後的調用這個函數的對象。所以,this指的就是這第一個參數。這裏就不講述二者的不一樣了【基本就是兩個函數的參數使用不一致】;jquery
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...ajax
在使用js操做dom的時候,很常見的會綁定事件;好比下面的將元素p綁定click事件,而後事件的回調函數中就可使用this;this指向這個時間的目標元素,也就是綁定事件的具體元素;json
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<elements.length ; i++){ elements[i].addEventListener('click', bluify, false); }
而在jQuery的使用中咱們基本就是使用$(this)來表示事件的目標元素;由於this就是e.target;而把一個dom元素變爲jQuery元素就是使用$把他抱起來就行了;app
在js中,window實現了WindowOrWorkerGlobalScope這個mixin的全部方法,其中最被常用的就是setTimeout、setInterval,由於這是一個異步的過程:dom
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的時候會出現等待的時長並非精準的參數中寫入的時間,緣由以下:
故而解決方法以下:
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;這個異步操做在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這面目,也就是上面的格式的數據。