摘要:這也是為什么在后,諸如這類寫越來越少的原因定時(shí)器對(duì)的影響調(diào)用的代碼運(yùn)行在與所在函數(shù)完全分離的執(zhí)行環(huán)境上。
總結(jié)下對(duì)this的學(xué)習(xí)與理解
轉(zhuǎn)眼前端的學(xué)習(xí)已有一年,日常寫代碼中經(jīng)常碰到this這個(gè)東西。特別是在用vue的時(shí)候,this還是有點(diǎn)多的,哈哈。
在翻閱了一部分書籍和一堆大佬的博客后,決定總結(jié)一下這些東西,下面談?wù)勎覍?duì)this的一些理解,如果有錯(cuò)誤,歡迎大家批評(píng)指正。如果可以給你帶來一些幫助,那是再好不過的了。
this實(shí)際上是在函數(shù)被調(diào)用時(shí)發(fā)生的綁定 2 如何判斷this綁定的對(duì)象是什么this是在運(yùn)行時(shí)基于函數(shù)的執(zhí)行環(huán)境綁定的,它的上下文取決于函數(shù)調(diào)用時(shí)的各種條件。
當(dāng)一個(gè)函數(shù)被調(diào)用時(shí),會(huì)創(chuàng)建一個(gè)活動(dòng)記錄(有時(shí)候也稱執(zhí)行上下文)。這個(gè)記錄會(huì)包含函數(shù)在哪里被調(diào)用,函數(shù)的調(diào)用方法、出今年入的參數(shù)等信息。this就是記錄其中一個(gè)屬性,會(huì)在函數(shù)執(zhí)行的過程中用到 --你不知道的JavaScript(上)
var name = "window" const obj1 = { name:"obj1", fn(){ console.log(this.name) } } obj1.fn()//"obj1"
var name = "window" const obj1 = { name:"obj1", fn(){ // "use strict" console.log(this.name) } } const obj2 = { name:"obj2", fn2:obj1.fn } obj2.fn2()//"obj2" obj1.fn()//"obj1"
#this的綁定與函數(shù)聲明的位置沒有聲明的位置沒有任何關(guān)系,只取決于函數(shù)的調(diào)用方式
#一般來說,誰最終調(diào)用了函數(shù),那么它就是this的綁定對(duì)象。
那在全局下調(diào)用函數(shù),this的綁定對(duì)象也就是全局對(duì)象
var name = "window" function fn(){ console.log(this.name) } fn()//"window"
下面這種情況為什么不是輸出window呢?
var name = "window" function fn(){ this.name = "fn" console.log(this.name) } fn()// "fn"
也是因?yàn)樵谌终{(diào)用這個(gè)函數(shù)的時(shí)候,this.name === window.name就把之前的值給覆蓋了,所以輸出就是 "fn"。
3. 那么如何判斷最終是誰調(diào)用了函數(shù) 函數(shù)調(diào)用的形式var name = "window" const obj1 = { name:"obj1", fn(){ // "use strict" console.log(this.name) } } const obj2 = { name:"obj2", fn2:obj1.fn } obj2.fn2()//"obj2" obj1.fn()//"obj1"
還是按照上面的代碼為例,這里
obj2.fn2()//完全等價(jià)于下面的 obj2.fn2.call(obj2) obj1.fn() 等于 obj1.fn.call(obj1)
同樣的
var name = "window" function fn(){ this.name = "fn" console.log(this.name) } fn() 等于 fn.call()這里面call不傳入?yún)?shù),既為undefined。在非嚴(yán)格模式下傳入undefined和null,都默認(rèn)是window。
var name = "window" function fn(){ "use strict" //為函數(shù)開啟嚴(yán)格模式 this.name = "fn" console.log(this.name) } fn() //則會(huì)報(bào)錯(cuò),這也同樣說明了函數(shù)在js內(nèi)部調(diào)用的形式
改改前面的代碼
var name = "window" const obj1 = { name:"obj1", fn(){ this.name = "fn" function inFn(){ console.log(this.name) } inFn() } } obj1.fn()//"window "
上面的inFn()也等同于inFn.call(),在全局調(diào)用它,自然也就是輸出window了。
關(guān)于箭頭函數(shù)和定時(shí)器 首先箭頭函數(shù)是沒有this的 ,它的作用域是和父級(jí)的上下文綁定在一起的var name = "window" const obj1 = { name:"obj1", fn(){ this.name = "fn" inFn= ()=>{ console.log(this.name) } inFn() } } obj1.fn()//"fn"
它的this就是上一層第一個(gè)包裹它的普通函數(shù)的this
所以用call/bind/apply調(diào)用箭頭函數(shù)的時(shí)候,是沒有效果的。
var name = "window" const obj1 = { name:"obj1", fn(){ this.name = "fn" inFn= ()=>{ console.log(this.name) } inFn() } } obj1.fn.call(window)//"fn"
這也是為什么在es6后,諸如_this=this這類寫越來越少的原因
定時(shí)器對(duì)this的影響setTimeout()調(diào)用的代碼運(yùn)行在與所在函數(shù)完全分離的執(zhí)行環(huán)境上。這會(huì)導(dǎo)致,這些代碼中包含的 this 關(guān)鍵字在非嚴(yán)格模式會(huì)指向 window (或全局)對(duì)象,嚴(yán)格模式下為 undefined,這和所期望的this的值是不一樣的。--MDN
備注:在嚴(yán)格模式下,setTimeout( )的回調(diào)函數(shù)里面的this仍然默認(rèn)指向window對(duì)象, 并不是undefined
this.name = "window" function Foo(){ this.name = "Foo" this.fn = function(){ console.log(this.name) } this.timer = function(){ setTimeout(this.fn) } } var obj = new Foo() obj.timer()//"window"
可以使用call/apply/bind調(diào)用改變this綁定對(duì)象。
this.name = "window" function Foo(){ this.name = "Foo" this.fn = function(){ console.log(this.name) } this.timer = function(){ setTimeout(this.fn.call(this)) } } var obj = new Foo() obj.timer()//"Foo"
還有箭頭函數(shù)
this.name = "window" const obj = { name:"obj", fn(){ console.log(1) setTimeout(()=>{ console.log(this.name) },1000) } } obj.fn()//"obj"也就是說從優(yōu)先級(jí)上說,有箭頭函數(shù)和定時(shí)器就不判斷是否由call/apply/bind調(diào)用 new對(duì)this的影響 new的優(yōu)先級(jí)很高,在沒有定時(shí)器影響的情況下是最高的
this.name = "window" function Foo(){ this.name = "Foo" this.fn = function(){ console.log(this.name) } this.timer = function(){ setTimeout(this.fn) } } var obj = new Foo() obj.timer() //"window"定時(shí)器只要是由new調(diào)用的,就綁定到新創(chuàng)建的對(duì)象,其他情況似乎都無法再改變this綁定的對(duì)象。
1.箭頭函數(shù)
function Foo(){ this.name="Foo" this.fn = ()=>{ console.log(this.name) } } var foo = new Foo() this.name = "window" //設(shè)置一下window.name的值 foo.fn() //"Foo" 輸出的是實(shí)例變量 console.log(this.name)//"window" 并沒有改變window.name的值
2.call/bind/apply
this.name = "window" function Foo(){ this.name="Foo" this.fn = ()=>{ console.log(this.name) } } var foo = new Foo() foo.fn.call(window)//"Foo" const tes = foo.fn.bind(window) tes() //"Foo"
##也就是說判斷一個(gè)運(yùn)行中的this綁定,就要找到這個(gè)函數(shù)的直接調(diào)用位置。
##按照上面介紹的優(yōu)先級(jí)順序進(jìn)行判斷便可以找到this的綁定對(duì)象。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/101847.html
摘要:而在構(gòu)造函數(shù)中,返回了的實(shí)例對(duì)象。在中直接返回過的實(shí)例,這里的是的真正構(gòu)造函數(shù)最后對(duì)外暴露入口時(shí),將字符與對(duì)等起來。因此當(dāng)我們直接使用創(chuàng)建一個(gè)對(duì)象時(shí),實(shí)際上是創(chuàng)建了一個(gè)的實(shí)例,這里的正真構(gòu)造函數(shù)是原型中的方法。 showImg(https://segmentfault.com/img/remote/1460000008749398); 早幾年學(xué)習(xí)前端,大家都非常熱衷于研究jQuery源...
摘要:對(duì)于所訪問的每個(gè)元素,函數(shù)應(yīng)該將該元素傳遞給所提供的回調(diào)函數(shù)。 HTML 在線閱讀Github地址 題目列表 HTML HTML和XHTML的區(qū)別 Html的語義化 Doctype的文檔類型 cookie、sessionSttorage、localStory區(qū)別 HTML全局屬性(global attribute)有哪些? 常見的瀏覽器內(nèi)核有哪些? 介紹一下你對(duì)瀏覽器內(nèi)核的理解?...
摘要:對(duì)于所訪問的每個(gè)元素,函數(shù)應(yīng)該將該元素傳遞給所提供的回調(diào)函數(shù)。 HTML 在線閱讀Github地址 題目列表 HTML HTML和XHTML的區(qū)別 Html的語義化 Doctype的文檔類型 cookie、sessionSttorage、localStory區(qū)別 HTML全局屬性(global attribute)有哪些? 常見的瀏覽器內(nèi)核有哪些? 介紹一下你對(duì)瀏覽器內(nèi)核的理解?...
摘要:對(duì)于所訪問的每個(gè)元素,函數(shù)應(yīng)該將該元素傳遞給所提供的回調(diào)函數(shù)。 HTML 在線閱讀Github地址 題目列表 HTML HTML和XHTML的區(qū)別 Html的語義化 Doctype的文檔類型 cookie、sessionSttorage、localStory區(qū)別 HTML全局屬性(global attribute)有哪些? 常見的瀏覽器內(nèi)核有哪些? 介紹一下你對(duì)瀏覽器內(nèi)核的理解?...
摘要:雖然今年沒有換工作的打算但為了跟上時(shí)代的腳步還是忍不住整理了一份最新前端知識(shí)點(diǎn)知識(shí)點(diǎn)匯總新特性,語義化瀏覽器的標(biāo)準(zhǔn)模式和怪異模式和的區(qū)別使用的好處標(biāo)簽廢棄的標(biāo)簽,和一些定位寫法放置位置和原因什么是漸進(jìn)式渲染模板語言原理盒模型,新特性,偽 雖然今年沒有換工作的打算 但為了跟上時(shí)代的腳步 還是忍不住整理了一份最新前端知識(shí)點(diǎn) 知識(shí)點(diǎn)匯總1.HTMLHTML5新特性,語義化瀏覽器的標(biāo)準(zhǔn)模式和怪...
閱讀 25648·2021-09-29 09:41
閱讀 4812·2021-09-10 11:20
閱讀 1931·2021-09-09 09:32
閱讀 1897·2019-08-30 15:44
閱讀 3205·2019-08-29 17:13
閱讀 2816·2019-08-29 14:14
閱讀 2071·2019-08-29 14:11
閱讀 3234·2019-08-29 12:36