摘要:的作用這段代碼可以在不同的上下文對(duì)象中重復(fù)使用函數(shù)和不用針對(duì)每個(gè)對(duì)象編寫不同版本的函數(shù)。顯然從字面意思來理解行不通執(zhí)行時(shí)的確向函數(shù)對(duì)象添加了一個(gè)屬性。的綁定和函數(shù)聲明的位置沒有任何關(guān)系,只取決于函數(shù)調(diào)用的方式調(diào)用位置。
this的作用
function identify() { return this.name.toUpperCase() } function speak() { var greeting = "Hello" + identify.call(this) console.log(greeting) } var me = { name: "aa" } var you = { name: "bb" } identify.call(me) // AA identify.call(you) // BB speak.call(me) // HelloAA speak.call(you) // HelloBB
這段代碼可以在不同的上下文對(duì)象中重復(fù)使用函數(shù)identify()和speak()、不用針對(duì)每個(gè)對(duì)象編寫不同版本的函數(shù)。
如果不使用this,那就需要給identify()和speak()顯示傳入一個(gè)上下文對(duì)象
function identify(context) { return context.name.toUpperCase() } function speak(context) { var greeting = "Hello" + identify(context) console.log(greeting) } identify(you) // BB speak(me) //HelloAA
this提供了一種更優(yōu)雅的方式來隱式”傳遞“一個(gè)對(duì)象引用,因此可以將API設(shè)計(jì)得更加簡(jiǎn)潔并且易于復(fù)用,隨著使用的模式越來越復(fù)雜,顯示傳遞上下文對(duì)象會(huì)讓代碼變得越來越混亂,使用this則不會(huì)這樣
this是什么人們很容易把this理解成指向函數(shù)自身,從英文翻譯上理解似乎是對(duì)的,下面看個(gè)例子:
function foo(num) { console.log("foo" + num) this.count++ console.log(this === window) // true } foo.count = 0 var i; for (i = 0; i < 10; i++) { if (i > 5) { foo(i) } } console.log(foo.count) // 0
console.log語句產(chǎn)生了4條輸出,證明foo(...)確實(shí)被調(diào)用了4次,但是foo.count任然是0。顯然從字面意思來理解this行不通
執(zhí)行foo.count = 0時(shí)的確向函數(shù)對(duì)象foo添加了一個(gè)屬性count。但是函數(shù)內(nèi)部代碼this.count的this并不是指向那個(gè)函數(shù)對(duì)象,指向的是全局對(duì)象window
那么this到底是什么呢?
this是在運(yùn)行時(shí)進(jìn)行綁定的,并不是在編寫時(shí)綁定,它的上下文取決于函數(shù)調(diào)用時(shí)的各種條件。this的綁定和函數(shù)聲明的位置沒有任何關(guān)系,只取決于函數(shù)調(diào)用的方式(調(diào)用位置)。
當(dāng)一個(gè)函數(shù)被調(diào)用時(shí),會(huì)創(chuàng)建一個(gè)活動(dòng)記錄(執(zhí)行上下文)。這個(gè)記錄會(huì)包含函數(shù)在哪里被調(diào)用(調(diào)用棧)、函數(shù)的調(diào)用方式、傳入的參數(shù)等信息。this就是這個(gè)記錄的一個(gè)屬性,會(huì)在函數(shù)執(zhí)行的過程中用到
首先介紹的是最常用的函數(shù)調(diào)用類型:獨(dú)立函數(shù)調(diào)用??梢园堰@條規(guī)則看作是無法應(yīng)用其他規(guī)則時(shí)的默認(rèn)規(guī)則,舉個(gè)例子:
function foo() { console.log(this.a) //2 } var a = 2 foo()
當(dāng)調(diào)用foo()時(shí),this.a被解析成了全局變量a,因?yàn)榇藭r(shí)foo()是直接使用不帶任何修飾的函數(shù)引用進(jìn)行調(diào)用的,只能用默認(rèn)綁定,無法應(yīng)用其他規(guī)則
但是當(dāng)嚴(yán)格模式,不能將全局對(duì)象應(yīng)用于默認(rèn)綁定,this會(huì)綁定到undefined
另一條需要考慮的規(guī)則是調(diào)用位置是否有上下文對(duì)象。舉個(gè)例子
function foo() { console.log(this.a) } var obj = { a: 2, foo: foo } obj.foo() // 2
當(dāng)foo()被調(diào)用時(shí),它的前面加上了對(duì)obj的引用,當(dāng)函數(shù)引用有上下文對(duì)象是,隱式綁定規(guī)則會(huì)把函數(shù)調(diào)用中this綁定到這個(gè)上下文對(duì)象。
對(duì)象屬性引用鏈中只有上一層或者說最后一層在調(diào)用位置中起作用。舉個(gè)例子
function foo() { console.log(this.a) } var obj2 = { a: 42, foo: foo } var obj1 = { a: 2, obj2: obj2 } obj1.obj2.foo() // 42隱式丟失
隱式綁定最常見的一個(gè)問題就是被隱式綁定的函數(shù)會(huì)丟失綁定對(duì)象,也就是會(huì)所它會(huì)應(yīng)用默認(rèn)綁定,從而把this綁定到全局對(duì)象或者undefine上,取決于是否嚴(yán)格模式,舉個(gè)例子:
function foo() { console.log(this.a) } var obj = { a: 2, foo: foo } var bar = obj.foo; var a = "global" bar() //相當(dāng)于執(zhí)行 foo() "global"
雖然bar是obj.foo的一個(gè)引用,但是實(shí)際上,它引用的是foo函數(shù)本身,因此此時(shí)的bar()其實(shí)是一個(gè)不帶任何修飾的函數(shù)調(diào)用,因此應(yīng)用了默認(rèn)綁定
顯示綁定javascript中提供的顯示綁定的方法就是大家都非常熟悉的call(...)、apply(...)和bind(...)方法,下面就簡(jiǎn)單介紹一下它們的用法:
call的語法為:
fun.call(thisArg[, arg1[, arg2[, ...]]])
apply的語法為:
fun.apply(thisArg, [argsArray])
它們的第一個(gè)參數(shù)對(duì)象是一個(gè)對(duì)象,是個(gè)this準(zhǔn)備的,接著在調(diào)用函數(shù)將其綁定到this。第二個(gè)參數(shù) call 方法接受的是若干個(gè)參數(shù)列表,而apply接收的是一個(gè)包含多個(gè)參數(shù)的數(shù)組。
bind()方法創(chuàng)建一個(gè)新的函數(shù), 當(dāng)被調(diào)用時(shí),將其this關(guān)鍵字設(shè)置為提供的值,在調(diào)用新函數(shù)時(shí),在任何提供之前提供一個(gè)給定的參數(shù)序列。因此:bind 是創(chuàng)建一個(gè)新的函數(shù),我們必須要手動(dòng)去調(diào)用,舉個(gè)例子:
var a ={ fn : function (a,b) { console.log( a + b) } } var b = a.fn; b.bind(a,1,2)() // 3new綁定
使用new來調(diào)用函數(shù),會(huì)自動(dòng)執(zhí)行下面的操作
創(chuàng)建(或者說構(gòu)造)一個(gè)全新的對(duì)象
這個(gè)新對(duì)象會(huì)被執(zhí)行[[Prototype]]連接
這個(gè)對(duì)象會(huì)綁定到函數(shù)調(diào)用的this
如果函數(shù)沒有返回其他對(duì)象,那么new表達(dá)式中的函數(shù)調(diào)用會(huì)自動(dòng)返回這個(gè)新對(duì)象
舉個(gè)例子:
function foo(a) { this.a = a } var bar = new foo(2) console.log(bar.a) // 2
使用new來調(diào)用foo(...)時(shí),會(huì)構(gòu)造一個(gè)新對(duì)象并把它綁定到foo(...)調(diào)用中的this上
綁定優(yōu)先級(jí)函數(shù)是否在new中調(diào)用(new綁定)?如果是的話this綁定的是新創(chuàng)建的對(duì)象
函數(shù)是否通過call、apply、bind(顯示綁定)?如果是的話,this綁定是指定的對(duì)象
函數(shù)是否在某個(gè)上下文對(duì)象中調(diào)用(隱式綁定)?如果是的話,this綁定的是那個(gè)上下文對(duì)象
如果都不是,使用默認(rèn)綁定,如果在嚴(yán)格模式下就綁定到undefined,否則綁定到全局對(duì)象
ES6中this指向ES6中的箭頭函數(shù)并不會(huì)使用上述的綁定規(guī)則,而是根據(jù)當(dāng)前的詞法作用域來決定this,具體來說,箭頭函數(shù)會(huì)繼承外層函數(shù)調(diào)用的this綁定(無論this綁定到什么)舉個(gè)例子:
function Timer() { this.s1 = 0; this.s2 = 0; setInterval(() => this.s1++, 1000); setInterval(function () { this.s2++; }, 1000); } var timer = new Timer(); setTimeout(() => console.log("s1: ", timer.s1), 1100); // 1 setTimeout(() => console.log("s2: ", timer.s2), 1100); // 0
上例中s1的值是在箭頭函數(shù)中,會(huì)繼承Timer函數(shù)作用域中的this,而s2在普通函數(shù)中,根據(jù)之前的綁定綁定規(guī)則可以看出此時(shí)的this會(huì)執(zhí)行默認(rèn)的綁定規(guī)則綁定到全局對(duì)象上
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/94254.html
摘要:作為構(gòu)造函數(shù)調(diào)用中沒有類,但是可以從構(gòu)造器中創(chuàng)建對(duì)象,并提供了運(yùn)算符來進(jìn)行調(diào)用該構(gòu)造器。構(gòu)造器的外表跟普通函數(shù)一樣,大部分的函數(shù)都可以當(dāng)做構(gòu)造器使用。如果構(gòu)造函數(shù)顯式的返回一個(gè)對(duì)象,那么則會(huì)指向該對(duì)象。 this 的指向 this 是 js 中定義的關(guān)鍵字,它自動(dòng)定義于每一個(gè)函數(shù)域內(nèi),但是它的指向卻讓人很迷惑。在實(shí)際應(yīng)用中,this 的指向大致可以分為以下四種情況。 1.作為普通函數(shù)調(diào)...
摘要:再來看一個(gè)小的示例淘寶騰訊淘寶為什么輸出的依然是淘寶呢調(diào)用的是對(duì)象中的方法,方法里面有一個(gè)定時(shí)器,而定時(shí)器的一個(gè)參數(shù)是這里的指的就是的對(duì)象,然后方法里面有調(diào)用了,但是定時(shí)器中的指的是對(duì)象,所以最終調(diào)用的是對(duì)象中。 1.看前熱身 看一段代碼 var name = javascript; var obj = { name:js, foo:f...
摘要:語法參數(shù)這個(gè)對(duì)象將替代類里的對(duì)象可選在函數(shù)運(yùn)行時(shí)使用的值。如果該參數(shù)的值為或,則表示不需要傳入任何參數(shù)。更簡(jiǎn)單的講就是將和傳入函數(shù)執(zhí)行。 學(xué)了那么久前端,對(duì)apply、call這兩個(gè)函數(shù)的用法,還不是很掌握。今天看了很多網(wǎng)上的文章,我總結(jié)和歸納下用法。 Function.prototype.apply() apply() 方法調(diào)用一個(gè)具有給定this值的函數(shù),以及作為一個(gè)數(shù)組(或類似數(shù)...
摘要:但是有一個(gè)總的原則,那就是指的是,調(diào)用函數(shù)的那個(gè)對(duì)象使用主要分四種情況,討論下指針的用法和注意事項(xiàng)一純粹的函數(shù)調(diào)用這是函數(shù)的最通常用法,屬于全局性調(diào)用,因此就代表全局對(duì)象。 this是Javascript語言的一個(gè)關(guān)鍵字它代表函數(shù)運(yùn)行時(shí),自動(dòng)生成的一個(gè)內(nèi)部對(duì)象,只能在函數(shù)內(nèi)部使用,隨著函數(shù)使用場(chǎng)合的不同,this的值會(huì)發(fā)生變化。但是有一個(gè)總的原則,那就是this指的是,調(diào)用函數(shù)的那個(gè)對(duì)...
摘要:但是有一個(gè)總的原則,那就是指的是,調(diào)用函數(shù)的那個(gè)對(duì)象使用主要分四種情況,討論下指針的用法和注意事項(xiàng)一純粹的函數(shù)調(diào)用這是函數(shù)的最通常用法,屬于全局性調(diào)用,因此就代表全局對(duì)象。 this是Javascript語言的一個(gè)關(guān)鍵字它代表函數(shù)運(yùn)行時(shí),自動(dòng)生成的一個(gè)內(nèi)部對(duì)象,只能在函數(shù)內(nèi)部使用,隨著函數(shù)使用場(chǎng)合的不同,this的值會(huì)發(fā)生變化。但是有一個(gè)總的原則,那就是this指的是,調(diào)用函數(shù)的那個(gè)對(duì)...
摘要:含義既不指向函數(shù)本身,也不指向函數(shù)的詞法作用域。運(yùn)行時(shí)動(dòng)態(tài)綁定,并不是編寫綁定,上下文取決于函數(shù)調(diào)用的各種條件。 含義 既不指向函數(shù)本身,也不指向函數(shù)的詞法作用域。 運(yùn)行時(shí)動(dòng)態(tài)綁定,并不是編寫綁定,上下文取決于函數(shù)調(diào)用的各種條件。 指向取決于函數(shù)被調(diào)用的位置,也是在函數(shù)調(diào)用時(shí)候發(fā)生綁定。 解析 調(diào)用棧(可以比擬成函數(shù)調(diào)用鏈) 指到達(dá)當(dāng)前執(zhí)行位置所調(diào)用的所有函數(shù) so調(diào)用位置(函數(shù)...
閱讀 5099·2021-11-25 09:43
閱讀 1702·2021-10-27 14:18
閱讀 1066·2021-09-22 16:03
閱讀 1363·2019-08-30 13:19
閱讀 1584·2019-08-30 11:15
閱讀 1659·2019-08-26 14:04
閱讀 3135·2019-08-23 18:40
閱讀 1175·2019-08-23 18:17