this是屬性和方法「當前」(執行時)所在的物件。this是函式呼叫時發生的繫結,它的值只取決於呼叫位置(箭頭函式除外)。
函式呼叫的時候會產生乙個執行上下文,this是對這個執行上下文的記錄。
❌誤區需要注意:
this不是指向函式本身;this和函式作用域無關;this和宣告位置無關係,只和呼叫位置有關係。
名次解釋:
呼叫棧: 到達當前執行位置呼叫的所有的函式。
既然this是呼叫時繫結的物件,我們只需要搞清楚this的繫結規則:
當函式呼叫時,如果函式直接呼叫,沒有任何修飾(函式前沒有任何物件),則預設繫結this到window。
如果使用嚴格模式,預設繫結到undefined。
所以,立即執行函式在任何位置,函式內部的this,永遠指向window(嚴格模式下undefined)。
當函式呼叫時,前面有上下文物件時,隱式繫結規則將this繫結到該物件上。
如果多層巢狀,繫結到最近的上下文物件(obj1.obj2)上。
js監聽函式的**函式,將this繫結到呼叫的dom物件上。
click me
前端開發中this最容易出錯的地方,就是隱式繫結丟失導致的this指向window(嚴格模式undefined)的問題。
隱式繫結丟失常見的幾種情況:
1.賦值給變數
2.作為自定義函式的**函式傳參
將上下文物件的函式作為引數傳入**函式,相當於賦值給引數變數。
這個問題可以解釋,為什麼react類元件中事件**函式觸發必須繫結this:
首先: react類元件中,建構函式、例項方法、靜態方法都是在嚴格模式下執行的。
import react from 'react';import reactdom from 'react-dom';
constructor(props)
onclick()
//onclick後面跟的是**函式,相當於callback = this.onclick;
//click me
//呼叫的時候是直接呼叫callback(),所以this應該是預設繫結
//由因為在例項方法中,是嚴格模式,所以是undefined
//要想在onclick方法中使用this,需要進行this顯式繫結
render() >click me
) }
}reactdom.render(
3. 作為j**ascript一些內建函式的**函式傳參
常見的有settimeout,陣列的遍歷函式如foreach, map, reduce, reduceright, some, every,filter,flatmap等
上面的三種情況都是隱式繫結丟失,導致this使用預設繫結的情況。還有一種**函式this被修改的情況。
ps: this繫結隱式修改
這種情況一般是,有些js庫中將事件處理器將**函式繫結到dom元素上。
如:jquery庫的事件**函式
click me 1
三種方法呼叫有區別,具體的可以參考三種方法的詳細介紹。
通過這三種方法,可以將函式this繫結到乙個不相關的物件, 還可以解決隱式繫結中隱式丟失的問題。
1. 指定物件
2. react中事件處理繫結this-不傳參
react類元件中,不繫結,預設this嚴格模式下是undefined,需要將函式內部this繫結繫結到當前元件上。
1. 使用箭頭函式固定this的指向
箭頭函式內部沒有this(箭頭函式不能使用new命令),所以箭頭函式的this繫結**塊外部作用域(函式作用域或者全域性作用域)的this。即定義時所在物件。
這點和普通的this是執行時所在物件不同。而且箭頭函式繫結作用域後不能修改(不能通過bind等方法修改)。
//箭頭函式固定this的方法適用於settimeout,類例項方法
constructor(props)add= () =>,1000)
}render() >click me
) }
}
有一點需要注意: 箭頭函式繫結的是**塊外部的函式或者全域性作用域。物件沒有作用域。
const shape =,p: () =>
}console.log(shape.p());
//window/嚴格模式下undefined
console.log(shape.q()); //
shape
2. 使用bind方法在建構函式中進行繫結
constructor(props)
add(e).bind(this), 1000)
}render() >click me
) }
}3. react中事件處理繫結this-傳參
只有傳參的時候才使用這些繫結方式;
因為它每次渲染生成新的**函式,如果作為props傳參,會進行額外的重新渲染。
1. 在事件屬性的**函式中使用箭頭函式
這種方式,必須顯式的傳遞事件物件e
constructor(props)
add(e)
render() >click me
) }
}2. 在事件屬性的**函式中使用bind方法
這種方式會隱式的傳遞事件物件e, 在其他引數之後
constructor(props)
add(id, e)
render() >click me
) }
}3. 使用data-*屬性傳遞引數
該方法不會在render後每次生成新函式;
add = (e) =>render()
4. this賦值給變數傳參
針對settimeout等**函式隱式繫結丟失的情況,除了上面的箭頭箭頭函式和bind方法,還有
constructor(props)
add(e) , 1000)
}render() >click me
) }
}5. 使用一些原生函式的自身引數
陣列的很多處理方法,以**函式作為引數,這些**函式中this會預設是window/undefined(嚴格模式);
他們提供最後乙個引數用於繫結內部的this。不適用於settimeout.
constructor(props)
add(e),that);//
第二個引數是被繫結的this物件
} render() >click me
) }
}使用new命令例項化乙個建構函式的時候,邏輯如下:
1)建立乙個空物件
2)將物件的原型物件指向建構函式的prototype屬性
3)將這個空物件繫結到this
4) 沒有其他返回物件的情況下,返回this
new繫結 > 顯示繫結 > 隱式繫結 > 預設繫結
ps: 特殊的this取值
在class中,this除了指代類的例項物件外,在靜態方法中的this有別的指向:
靜態方法中,this指向當前類。
資料繫結問題
1.nexttick 當資料變化的時候dom並不會立馬渲染檢視,而是有一定的延遲,等待資料不變的時候再行渲染 所以就會非同步操作 console.log id val this.id 1 console.log id val 如果我們settimeout函式也行,但是不合理 所以為了解決引入新概念 ...
早繫結的問題與動態繫結
物件可以作為自己的類或者作為它的基類 父類 的物件來使用。還能通過基類的位址來操作它。取乙個物件的位址 指標或引用 並將其作為基類的位址來處理,稱為向上型別轉換。也就是說,父類引用或指標可以指向子類物件,通過父類指標或引用操作子類物件。class human class dog public hum...
控制項繫結的問題
控制項繫結的問題 vcl元件開發及應用 我動態建立了tcpserver,adoonnection,乙個socket對應乙個資料庫連線,想將tcpserver和adoonnection繫結,如下 for i 0 to 5 do begin adoconn i tadoconnection.create...