js 里面令人头疼的 this
JS中this相關(guān)問(wèn)題梳理
this 就是 js 里的關(guān)鍵字,有特殊意義,代表函數(shù)執(zhí)行主體
一、定義
- 函數(shù)執(zhí)行主體(不是作用域):意思是誰(shuí)把函數(shù)執(zhí)行了,那么執(zhí)行主體就是誰(shuí)
二、使用情況
但是要是在箭頭函數(shù)里使用this,它就會(huì)往上一級(jí)作用域查找,如果上一級(jí)作用域也沒(méi)有,那就繼續(xù)查找,直到找到全局作用域window為止
let obj = {num: 2,fn: function() {// this --> objlet m = () => {// this --> objconsole.log(this.num); // obj (要向上一級(jí)查找)}m();} } obj.fn();構(gòu)造函數(shù)里的this是當(dāng)前的實(shí)例
實(shí)例原型上的公有方法里的this一般是當(dāng)前實(shí)例(下面改變this的方法中有所體現(xiàn))
給元素綁定事件行為,那事件里的this就是當(dāng)前被綁定的元素本身
三、面向?qū)ο笾杏嘘P(guān)私有/公有方法中的THIS問(wèn)題
總結(jié)下來(lái)this在面向?qū)ο笾?#xff0c;主要還是看誰(shuí)執(zhí)行的,也就是執(zhí)行函數(shù)點(diǎn)前是誰(shuí)
四、改變this指向:call/apply/bind
每一個(gè)函數(shù)(普通函數(shù)/構(gòu)造函數(shù)/內(nèi)置類(lèi))都是Function這個(gè)內(nèi)置類(lèi)的實(shí)例,所以函數(shù).__proto__ === Function.prototype,函數(shù)可以直接調(diào)取Function原型上的方法
- call / apply / bind
- 原型上提供的三個(gè)公有屬性方法
- 每一個(gè)函數(shù)都可以調(diào)用這個(gè)方法執(zhí)行
- 這些方法都是用來(lái)改變函數(shù)中的this指向的
函數(shù)基于原型鏈扎找到Function.prototype.call這個(gè)方法,并且把它執(zhí)行,在call方法執(zhí)行的時(shí)候改變里面的this關(guān)鍵字
- 讓當(dāng)前的函數(shù)執(zhí)行
- 把函數(shù)中的this指向改為第一個(gè)傳遞給call的實(shí)參
- 把傳遞給call其余的實(shí)參,當(dāng)做參數(shù)信息傳遞給當(dāng)前函數(shù)
注意:
- 如果執(zhí)行call一個(gè)實(shí)參都沒(méi)有傳遞,非嚴(yán)格模式下是讓函數(shù)中的this指向window,嚴(yán)格模式下指向的是undefined
- fn.call(null);
- //=> this.window
- 嚴(yán)格下是this(第一個(gè)參數(shù)傳遞的是null/undefined/不傳,非嚴(yán)格模式下this指向window,嚴(yán)格模式下傳遞的是誰(shuí)this就是誰(shuí),不傳this是undefined)
使用方法:
window.name = 'WINDOW'; let obj = {name: 'OBJ'}; function fn(n, m) {console.log(this.name); } fn(10, 20); // WINDOW --> 因?yàn)楹瘮?shù)剛開(kāi)始指向window fn.call(obj); // OBJ --> 改變函數(shù)this指向,此時(shí)函數(shù)fn指向obj fn.call(obj, 10, 20); // OBJ fn.call(10, 20); // undefined可以得出:
- 一個(gè) call 是讓左邊函數(shù)之后執(zhí)行(this是傳遞的參數(shù))
- 多個(gè) call 是讓最后傳參的函數(shù)執(zhí)行(this是window/undefined)
2、apply
和call方法一樣,都是把函數(shù)執(zhí)行,并且改變里面的this關(guān)鍵字,唯一的區(qū)別就是傳遞給函數(shù)參數(shù)的方式不一樣
- call是一個(gè)個(gè)傳參
- apply是按照數(shù)組傳參
3、bind
和call/apply一樣,也是用來(lái)改變函數(shù)中的this關(guān)鍵字,只不過(guò)基于bind改變this,當(dāng)前方法并沒(méi)有被執(zhí)行,類(lèi)似于預(yù)先改變this
- bind是預(yù)處理this,他并不會(huì)讓函數(shù)執(zhí)行
- bind方法的返回值是一個(gè)改變this之后的新函數(shù)
作用:
-
把函數(shù)中的this指向通過(guò)預(yù)處理的方式改為第一個(gè)傳遞給bind的實(shí)參
-
一般使用在綁定點(diǎn)擊事件,不讓函數(shù)立即執(zhí)行
注意:
- 在IE6~8中不支持 bind 方法
- 預(yù)先做啥事情的思想被稱(chēng)為“柯理化函數(shù)”
優(yōu)點(diǎn):
- bind的好處是:通過(guò)bind方法只是預(yù)先把fn中的this修改為obj,此時(shí)fn并沒(méi)有執(zhí)行,當(dāng)點(diǎn)擊事件觸發(fā)才會(huì)執(zhí)行fn(call/apply都是通過(guò)改變this的同時(shí)立即把方法執(zhí)行)
總結(jié)
以上是生活随笔為你收集整理的js 里面令人头疼的 this的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: sqoop导入hive时间格式问题解决方
- 下一篇: 02 - java 标识符命名规范