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