400-650-7353
JavaScript中this的存在為我們寫代碼提供了非常多的幫助,但是在具體使用的時候this的具體指向會變得各不相同,在本篇文章中,我們將詳細討論this的指向機制。
首先我們要明確一個概念,this既不是指向當前函數,也不是某個固定的對象,而是函數在執行時的環境對象。也就是是說,函數內this的指向只和函數是如何被調用的有關,和函數的定義方式以及位置等沒有必然的聯系。
1. 最普通的函數調用
上述案例中,我們可以認為全局函數demo是頂層對象window的方法,所以可以認為是window在調用demo函數,所以其中的this指向的是window對象。
- function demo(){
- console.log(this);
- }
- demo();
2. 對象方法中的this
在上面這個案例中,執行的雖然也是demo函數,但是在我們是通過obj對象對demo函數的引用訪問到demo函數的,所以可以認為是obj對象在調用函數demo,函數內this的this就要指向obj對象。
- function demo(){
- console.log(this);
- }
- var obj = {
- foo:demo
- }
- obj.foo();
3. 定時器中的this
在第一個定時器中,通過定時器執行函數demo時,可以依然認為demo是全局對象window的方法,所以是window對象在調用demo函數,所以this依然指向window。而第二個定時器中是一個匿名函數,一般匿名函數的執行具有全局性,也就是可以認為匿名函數是是在全局環境中被調用的,那么該定時器函數內的this就指向了全局環境對象window。
- function demo(){
- console.log(this);
- }
- setTimeout(demo,1000);
- setTimeout(function(){
- console.log(this);
- },2000);
[page]
4. 事件綁定中的this
事件處理函數中的this,無論是綁定的是命名函數還是匿名函數,都可以認為是元素引用的一個方法,雖然這種函數的調用具有其隱蔽性,但是我們還是應該視為其執行環境是元素引用,所以this指向觸發事件(調用方法)的元素。而addEventListener 方法中的事件函數默認是作為調用addEventListener對象的方法,所以同樣觸發事件的元素。
- oBox.onclick = function(){
- console.log(this);
- }
- // oBox.onclick();
- oBox.addEventListener("click",function(){
- console.log(this)
- });
5. 閉包中的函數
在上述案例中,我們雖然是通過調用obj對象的foo方法獲取了匿名函數,但是由于匿名函數的執行具有的全局性,而這時并沒有出現實際的其他調用者,所以函數內的this指向全局對象window。當然這只是一個常見的案例,this的指向具體情況還是要結合實際調用者具體分析。
- var obj = {
- foo:function(){
- return function(){
- console.log(this);
- }
- }
- }
- obj.foo()();
6. new 操作符調用函數
new 操作符調用函數內的this是一個恒定值,指向的是函數執行前創建的對象。
- function CreateStu(){
- console.log(this);
- }
- new CreateStu();
7. 其他的this
call和apply方法(作用相同,參數不同)都可以強制改變this的指向,可以將函數執行時的this指向方法的第一個參數。
- var obj1 = {
- foo:function(){
- console.log(this);
- }
- }
- var obj2 = {}
- obj1.foo.call(obj2);