千鋒教育JavaScript全套視頻教程(10天學(xué)會(huì)Js,前端javascrip

JavaScript 中的 this
關(guān)鍵字是一個(gè)非常重要且常用的概念,它代表當(dāng)前函數(shù)執(zhí)行時(shí)的上下文對(duì)象。this
的指向在 JavaScript 中是非常靈活的,不同的情況下指向不同的對(duì)象,下面我們來(lái)詳細(xì)講解 this
的指向問(wèn)題。
常見(jiàn)this的綁定
1. 默認(rèn)綁定
當(dāng)函數(shù)沒(méi)有明確指定 this
的綁定對(duì)象時(shí),即在非嚴(yán)格模式下,this
的指向會(huì)默認(rèn)綁定到全局對(duì)象上(在瀏覽器環(huán)境下是 window
對(duì)象,在 Node.js 環(huán)境下是 global
對(duì)象),例如:
js 復(fù)制代碼 function foo() { console.log(this); } foo(); // 在瀏覽器環(huán)境下輸出 window 對(duì)象,在 Node.js 環(huán)境下輸出 global 對(duì)象
2. 隱式綁定
當(dāng)函數(shù)作為對(duì)象的方法進(jìn)行調(diào)用時(shí),this
的指向會(huì)隱式綁定到調(diào)用該方法的對(duì)象上,例如:
js 復(fù)制代碼 const obj = { name: 'John', sayName() { console.log(this.name); } }; obj.sayName(); // 輸出 John
在上面的例子中,sayName
方法的調(diào)用者是 obj
對(duì)象,因此 this
的指向就會(huì)隱式地綁定到 obj
對(duì)象上,從而訪問(wèn)到 obj
對(duì)象的 name
屬性。
需要注意的是,如果在對(duì)象內(nèi)部定義一個(gè)函數(shù),并將其作為參數(shù)傳遞到其他函數(shù)中,那么該函數(shù)內(nèi)部的 this
指向可能會(huì)發(fā)生改變,例如:
js 復(fù)制代碼 const obj = { name: 'John', sayName() { console.log(this.name); }, foo() { setTimeout(this.sayName, 1000); } }; obj.foo(); // 在一些情況下會(huì)輸出 undefined,而不是 John
在上面的例子中,foo
方法內(nèi)部通過(guò) setTimeout
調(diào)用了 sayName
方法,由于 setTimeout
是一個(gè)獨(dú)立的函數(shù)調(diào)用,因此其中的 this
指向會(huì)被綁定到全局對(duì)象上,導(dǎo)致 sayName
方法內(nèi)部訪問(wèn)不到 obj
對(duì)象的 name
屬性。
3. 顯示綁定
通過(guò)使用 call
、apply
或者 bind
等函數(shù),可以顯式地綁定 this
的指向,例如:
js 復(fù)制代碼 function foo() { console.log(this); } const obj = { name: 'John' }; foo.call(obj); // 輸出 { name: 'John' } foo.apply(obj); // 輸出 { name: 'John' } const bar = foo.bind(obj); bar(); // 輸出 { name: 'John' }
在上面的例子中,通過(guò) call
、apply
或者 bind
函數(shù),將 foo
函數(shù)的 this
指向顯式地綁定到 obj
對(duì)象上,從而訪問(wèn)到 obj
對(duì)象的屬性。
需要注意的是,當(dāng)使用call
、apply
或者 bind
函數(shù)顯式綁定 this
指向時(shí),如果同時(shí)使用了默認(rèn)綁定,那么默認(rèn)綁定會(huì)被忽略。例如:
js 復(fù)制代碼 function foo() { console.log(this); } const obj = { name: 'John' }; foo.call(obj); // 輸出 { name: 'John' } foo(); // 輸出全局對(duì)象,因?yàn)榇藭r(shí)使用了默認(rèn)綁定
在上面的例子中,雖然 foo.call(obj)
顯式綁定了 this
指向,但在 foo()
調(diào)用時(shí)依然使用了默認(rèn)綁定,因此 this
的指向是全局對(duì)象。
4. new 綁定
在使用 new
關(guān)鍵字調(diào)用構(gòu)造函數(shù)時(shí),this
的指向會(huì)被綁定到新創(chuàng)建的對(duì)象上,例如:
js 復(fù)制代碼 function Person(name) { this.name = name; } const john = new Person('John'); console.log(john.name); // 輸出 John
在上面的例子中,通過(guò) new
關(guān)鍵字調(diào)用 Person
構(gòu)造函數(shù)創(chuàng)建了一個(gè)新的對(duì)象 john
,此時(shí) this
的指向會(huì)被自動(dòng)綁定到新創(chuàng)建的對(duì)象 john
上,從而將 name
屬性添加到 john
對(duì)象中。
需要注意的是,如果構(gòu)造函數(shù)內(nèi)部返回一個(gè)對(duì)象,那么 this
的指向會(huì)被忽略,返回的對(duì)象會(huì)被作為新創(chuàng)建的對(duì)象返回,例如:
js 復(fù)制代碼 function Person(name) { this.name = name; return { age: 20 }; } const john = new Person('John'); console.log(john); // 輸出 { age: 20 }
在上面的例子中,雖然 Person
構(gòu)造函數(shù)內(nèi)部使用了 this
,但返回了一個(gè)新的對(duì)象 { age: 20 }
,因此 this
的指向會(huì)被忽略,john
對(duì)象會(huì)被返回成為 new Person('John')
的結(jié)果。
5.箭頭展示中this的指向
在箭頭函數(shù)中,this
的指向是固定的,始終指向外層函數(shù)的 this
。箭頭函數(shù)的 this
指向是靜態(tài)的,一旦確定了指向,就無(wú)法更改。例如:
js 復(fù)制代碼 function foo() { return () => { console.log(this); } } const obj = { name: 'John' }; const bar = foo.call(obj); // bar 是一個(gè)箭頭函數(shù) bar(); // 輸出 { name: 'John' }
在上面的例子中,foo()
函數(shù)返回了一個(gè)箭頭函數(shù),該箭頭函數(shù)的 this
指向 foo()
函數(shù)的 this
,即 obj
對(duì)象。當(dāng)調(diào)用 bar()
函數(shù)時(shí),箭頭函數(shù)的 this
指向仍然是 obj
對(duì)象,因此輸出了 { name: 'John' }
。
需要注意的是,如果箭頭函數(shù)是在全局作用域中定義的,那么它的 this
指向就是全局對(duì)象。例如:
js 復(fù)制代碼 const arrow = () => { console.log(this); }; arrow(); // 輸出全局對(duì)象
在上面的例子中,arrow()
是在全局作用域中定義的箭頭函數(shù),因此它的 this
指向是全局對(duì)象。
需要注意的問(wèn)題
除了上面提到的情況外,還有一些值得注意的地方:
- 嚴(yán)格模式下的默認(rèn)綁定
在嚴(yán)格模式下,默認(rèn)綁定的行為會(huì)與非嚴(yán)格模式有所不同。在非嚴(yán)格模式下,如果函數(shù)調(diào)用不符合任何綁定規(guī)則,則默認(rèn)綁定會(huì)綁定到全局對(duì)象上。而在嚴(yán)格模式下,如果函數(shù)調(diào)用不符合任何綁定規(guī)則,則默認(rèn)綁定的 this
值會(huì)被設(shè)置為 undefined
,例如:
js 復(fù)制代碼 function foo() { 'use strict'; console.log(this); } foo(); // 輸出 undefined
在上面的例子中,雖然 foo()
函數(shù)沒(méi)有任何顯式綁定,但在嚴(yán)格模式下,this
的值會(huì)被設(shè)置為 undefined
。
- DOM 事件處理函數(shù)中的 this
在處理 DOM 事件時(shí),事件處理函數(shù)中的 this
指向的是觸發(fā)事件的元素。例如:
html 復(fù)制代碼 <button id="my-button">Click me</button> js 復(fù)制代碼 const button = document.getElementById('my-button'); button.addEventListener('click', function() { console.log(this); // 輸出按鈕元素 });
在上面的例子中,事件處理函數(shù)中的 this
指向的是按鈕元素,因?yàn)樵摵瘮?shù)是通過(guò)按鈕元素的 addEventListener
方法注冊(cè)的。
- jQuery 中的 this
在 jQuery 中,大多數(shù)方法都會(huì)返回 jQuery 對(duì)象,以便支持鏈?zhǔn)秸{(diào)用。在 jQuery 方法鏈中,this
指向的始終是 jQuery 對(duì)象本身,例如:
js 復(fù)制代碼 $('.my-class') .css('color', 'red') // 返回 jQuery 對(duì)象,this 指向的是該對(duì)象 .addClass('my-class') // 返回 jQuery 對(duì)象,this 指向的是該對(duì)象 .on('click', function() { console.log(this); // 輸出點(diǎn)擊的元素 });
在上面的例子中,$('.my-class')
方法返回的是 jQuery 對(duì)象,后續(xù)的方法鏈中的 this
始終指向該對(duì)象。在事件處理函數(shù)中,this
指向的是觸發(fā)事件的元素。
總結(jié)
- 默認(rèn)綁定:在函數(shù)調(diào)用中,如果沒(méi)有其他綁定規(guī)則適用,則默認(rèn)綁定到全局對(duì)象或
undefined
(嚴(yán)格模式下)。 - 隱式綁定:在函數(shù)調(diào)用中,如果函數(shù)作為對(duì)象的方法被調(diào)用,則隱式綁定到該對(duì)象。
- 顯式綁定:可以使用
call
、apply
或bind
方法顯式指定函數(shù)的this
。 new
綁定:在使用new
運(yùn)算符創(chuàng)建新對(duì)象時(shí),會(huì)自動(dòng)將this
綁定到新對(duì)象上。- 箭頭函數(shù)綁定:箭頭函數(shù)的
this
始終指向外層函數(shù)的this
,無(wú)法通過(guò)call
、apply
或bind
方法更改。 - 嚴(yán)格模式下的默認(rèn)綁定:在嚴(yán)格模式下,默認(rèn)綁定的
this
值會(huì)被設(shè)置為undefined
。 - DOM 事件處理函數(shù)中的
this
:在處理 DOM 事件時(shí),事件處理函數(shù)中的this
指向的是觸發(fā)事件的元素。 - jQuery 中的
this
:在 jQuery 方法鏈中,this
始終指向 jQuery 對(duì)象本身,在事件處理函數(shù)中指向觸發(fā)事件的元素。 - 誰(shuí)在調(diào)用函數(shù),
this
指向就是誰(shuí),不然就是全局對(duì)象。 然而,也存在一些特殊情況,其中this
的指向不僅僅取決于調(diào)用函數(shù)的對(duì)象。例如,使用call
、apply
或者bind
等方法可以顯式地指定函數(shù)的this
。此外,箭頭函數(shù)具有固定的詞法作用域,其中的this
始終指向外層函數(shù)的this
,而不會(huì)被調(diào)用方式所改變。
作者:伊澤瑞爾
鏈接:https://juejin.cn/post/7234817882902790203
來(lái)源:稀土掘金
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。