您好,登錄后才能下訂單哦!
今天小編給大家分享一下Javascript中的this怎么應用的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
從call方法開始
call 方法允許切換函數執行的上下文環境(context),即 this 綁定的對象。
大多數介紹 this 的文章中都會把 call 方法放到***介紹,但此文我們要把 call 方法放在***位介紹,并從 call 方法切入來研究 this ,因為 call 函數是顯式綁定 this 的指向,我們來看看它如何模擬實現(不考慮傳入 null 、 undefined 和原始值):
Function.prototype.call = function(thisArg) { var context = thisArg; var arr = []; var result; context.fn = this; for (let i = 1, len = arguments.length; i < len; i++) { arr.push('arguments[' + i + ']'); } result = eval("context.fn(" + arr + ")"); delete context.fn; return result; }
從以上代碼我們可以看到,把調用 call 方法的函數作為***個參數對象的方法,此時相當于把***個參數對象作為函數執行的上下文環境,而 this 是指向函數執行的上下文環境的,因此 this 就指向了***個參數對象,實現了 call 方法切換函數執行上下文環境的功能。
對象方法中的this
在模擬 call 方法的時候,我們使用了對象方法來改變 this 的指向。調用對象中的方法時,會把對象作為方法的上下文環境來調用。
既然 this 是指向執行函數的上下文環境的,那我們先來研究一下調用函數時的執行上下文情況。
下面我門來看看調用對象方法時執行上下文是如何的:
var foo = { x : 1, getX: function(){ console.log(this.x); } } foo.getX();
從上圖中,我們可以看出getX方法的調用者的上下文是foo,因此getX方法中的 this 指向調用者上下文foo,轉換成 call 方法為foo.getX.call(foo)。
下面我們把其他函數的調用方式都按調用對象方法的思路來轉換。
構造函數中的this
function Foo(){ this.x = 1; this.getX = function(){ console.log(this.x); } } var foo = new Foo(); foo.getX();
執行 new 如果不考慮原型鏈,只考慮上下文的切換,就相當于先創建一個空的對象,然后把這個空的對象作為構造函數的上下文,再去執行構造函數,***返回這個對象。
var newMethod = function(func){ var context = {}; func.call(context); return context; } function Foo(){ this.x = 1; this.getX = function(){ console.log(this.x); } } var foo = newMethod(Foo); foo.getX();
DOM事件處理函數中的this
DOMElement.addEventListener('click', function(){ console.log(this); });
把函數綁定到DOM事件時,可以當作在DOM上增加一個函數方法,當觸發這個事件時調用DOM上對應的事件方法。
DOMElement.clickHandle = function(){ console.log(this); } DOMElement.clickHandle();
普通函數中的this
var x = 1; function getX(){ console.log(this.x); } getX();
這種情況下,我們創建一個虛擬上下文對象,然后普通函數作為這個虛擬上下文對象的方法調用,此時普通函數中的this就指向了這個虛擬上下文。
那這個虛擬上下文是什么呢?在非嚴格模式下是全局上下文,瀏覽器里是 window ,NodeJs里是 Global ;在嚴格模式下是 undefined 。
var x = 1; function getX(){ console.log(this.x); } [viturl context].getX = getX; [viturl context].getX();
閉包中的this
var x = 1; var foo = { x: 2, y: 3, getXY: function(){ (function(){ console.log("x:" + this.x); console.log("y:" + this.y); })(); } } foo.getXY();
這段代碼的上下文如下圖:
這里需要注意的是,我們再研究函數中的 this 指向時,只需要關注 this 所在的函數是如何調用的, this 所在函數外的函數調用都是浮云,是不需要關注的。因此在所有的圖示中,我們只需要關注紅色框中的內容。
因此這段代碼我們關注的部分只有:
(function(){ console.log(this.x); })();
與普通函數調用一樣,創建一個虛擬上下文對象,然后普通函數作為這個虛擬上下文對象的方法立即調用,匿名函數中的 this 也就指向了這個虛擬上下文。
參數中的this
var x = 1; var foo = { x: 2, getX: function(){ console.log(this.x); } } setTimeout(foo.getX, 1000);
函數參數是值傳遞的,因此上面代碼等同于以下代碼:
var getX = function(){ console.log(this.x); }; setTimeout(getX, 1000);
然后我們又回到了普通函數調用的問題。
全局中的this
全局中的 this 指向全局的上下文
var x = 1; console.log(this.x);
復雜情況下的this
var x = 1; var a = { x: 2, b: function(){ return function(){ return function foo(){ console.log(this.x); } } } }; (function(){ var x = 3; a.b()()(); })();
看到上面的情況是有很多個函數,但我們只需要關注 this 所在函數的調用方式,首先我們來簡化一下如下:
var x = 1; (function(){ var x = 3; var foo = function(){ console.log(this.x); } foo(); });
this 所在的函數 foo 是個普通函數,我們創建一個虛擬上下文對象,然后普通函數作為這個虛擬上下文對象的方法立即調用。因此這個 this指向了這個虛擬上下文。在非嚴格模式下是全局上下文,瀏覽器里是 window ,NodeJs里是 Global ;在嚴格模式下是 undefined 。
以上就是“Javascript中的this怎么應用”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。