this繫結問題

2022-09-08 00:30:29 字數 3883 閱讀 9208

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...