电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

JavaScript this關鍵字的深入詳解

瀏覽:123日期:2023-10-05 13:28:22
一、前言

this關鍵字是JavaScript中最復雜的機制之一。它是一個很特別的關鍵字,被自動定義在所有函數的作用域中。對于那些沒有投入時間學習this機制的JavaScript開發者來說,this的綁定一直是一件非常令人困惑的事。

JavaScript this關鍵字的深入詳解

二、了解this

學習this的第一步是明白this既不指向函數自身也不指向函數的詞法作用域,你也許被這樣的解釋誤導過,但其實它們都是錯誤的。隨著函數使用場合的不同,this的值會發生變化。但總有一條原則就是 JS中的this代表的是當前行為執行的主體 ,在JS中主要研究的都是函數中的this,但并不是說只有在函數里才有this, this實際上是在函數被調用時發生的綁定,它指向什么完全取決于函數在哪里被調用 。如何的區分this呢?

三、this到底是誰

這要分情況討論,常見有五種情況:

1、函數執行時首先看函數名前面是否有'.',有的話,'.'前面是誰,this就是誰;沒有的話this就是window

function fn(){ console.log(this);}var obj={fn:fn};fn();//this->windowobj.fn();//this->objfunction sum(){ fn();//this->window}sum();var oo={ sum:function(){ console.log(this);//this->oo fn();//this->window }};oo.sum();

2、自執行函數中的this永遠是window

(function(){ //this->window })(); ~function(){ //this->window }();

3、給元素的某一個事件綁定方法,當事件觸發的時候,執行對應的方法,方法中的this是當前的元素,除了IE6~8下使用attachEvent(IE一個著名的bug)

DOM零級事件綁定

oDiv.onclick=function(){ //this->oDiv };

DOM二級事件綁定

oDiv.addEventListener('click',function(){ //this->oDiv },false);

在IE6~8下使用attachEvent,默認的this就是指的window對象

oDiv.attachEvent('click',function(){ //this->window });

我們大多數時候,遇到事件綁定,如下面例子這種,對于IE6~8下使用attachEvent不必太較真

function fn(){ console.log(this);}document.getElementById('div1').onclick=fn;//fn中的this就是#divldocument.getElementById('div1').onclick=function(){console.log(this);//this->#div1fn();//this->window};

4、在構造函數模式中,類中(函數體中)出現的this.xxx=xxx中的this是當前類的一個實例

function CreateJsPerson(name,age){//瀏覽器默認創建的對象就是我們的實例p1->thisthis.name=name;//->p1.name=namethis.age=age;this.writeJs=function(){console.log('my name is'+this.name +',i can write Js'); };//瀏覽器再把創建的實例默認的進行返回}var p1=new CreateJsPerson('尹華芝',48);

必須要注意一點: 類中某一個屬性值(方法),方法中的this需要看方法執行的時候,前面是否有'.',才能知道this是誰 。大家不妨看下接下來的這個例子,就可明白是啥意思。

function Fn(){this.x=100;//this->f1this.getX=function(){console.log(this.x);//this->需要看getX執行的時候才知道 }}var f1=new Fn;f1.getX();//->方法中的this是f1,所以f1.x=100var ss=f1.getX;ss();//->方法中的this是window ->undefined

5.call、apply和bind

我們先來看一個問題,想在下面的例子中this綁定obj,怎么實現?

var obj={name:'浪里行舟'};function fn(){console.log(this);//this=>window}fn();obj.fn();//->Uncaught TypeError:obj.fn is not a function

如果直接綁定obj.fn(),程序就會報錯。這里我們應該用fn.call(obj)就可以實現this綁定obj,接下來我們詳細介紹下call方法:

call方法的作用:

①首先我們讓原型上的call方法執行,在執行call方法的時候,我們讓fn方法中的this變為第一個參數值obj;然后再把fn這個函數執行。

②call還可以傳值,在嚴格模式下和非嚴格模式下,得到值不一樣。

//在非嚴格模式下var obj={name:'浪里行舟 '};function fn(num1,num2){console.log(num1+num2);console.log(this);}fn.call(100,200);//this->100 num1=200 num2=undefinedfn.call(obj,100,200);//this->obj num1=100 num2=200fn.call();//this->windowfn.call(null);//this->windowfn.call(undefined);//this->window

//嚴格模式下 fn.call();//在嚴格模式下this->undefinedfn.call(null);// 在嚴格模式 下this->nullfn.call(undefined);//在嚴格模式下this->undefined

**apply和call方法的作用是一模一樣的,都是用來改變方法的this關鍵字并且把方法

執行,而且在嚴格模式下和非嚴格模式下對于第一個參數是null/undefined這種情況的規

律也是一樣的。**

兩者唯一的區別:call在給fn傳遞參數的時候,是一個個的傳遞值的,而apply不是一個個傳,而是把要給fn傳遞的參數值統一的放在一個數組中進行操作。但是也相當子一個個的給fn的形參賦值。 總結一句話:call第二個參數開始接受一個參數列表,apply第二個參數開始接受一個參數數組

fn.call(obj,100,200);fn.apply(obj,[100,200]);

bind:這個方法在IE6~8下不兼容,和call/apply類似都是用來改變this關鍵字的 ,但是和這兩者有明顯區別:fn.call(obj,1,2);//->改變this和執行fn函數是一起都完成了

fn.bind(obj,1,2);//->只是改變了fn中的this為obj,并且給fn傳遞了兩個參數值1、2, 但是此時并沒有把fn這個函數執行var tempFn=fn.bind(obj,1,2);tempFn(); //這樣才把fn這個函數執行

bind體現了預處理思想:事先把fn的this改變為我們想要的結果,并且把對應的參數值也準備好,以后要用到了,直接的執行即可。

call和apply直接執行函數,而bind需要再一次調用。

var a ={ name : 'Cherry', fn : function (a,b) { console.log( a + b) } } var b = a.fn; b.bind(a,1,2)

JavaScript this關鍵字的深入詳解

上述代碼沒有執行,bind返回改變了上下文的一個函數,我們必須要手動去調用:

b.bind(a,1,2)() //3

必須要聲明一點:遇到第五種情況(call apply和bind),前面四種全部讓步。

四、箭頭函數this指向

箭頭函數正如名稱所示那樣使用一個“箭頭”(=>)來定義函數的新語法,但它優于傳統的函數,主要體現兩點: 更簡短的函數并且不綁定this 。

var obj = { birth: 1990, getAge: function () { var b = this.birth; // 1990 var fn = function () { return new Date().getFullYear() - this.birth; // this指向window或undefined }; return fn(); }};

現在,箭頭函數完全修復了this的指向, 箭頭函數沒有自己的this,箭頭函數的this不是調用的時候決定的,而是在定義的時候處在的對象就是它的this 。

換句話說, 箭頭函數的this看外層的是否有函數,如果有,外層函數的this就是內部箭頭函數的this,如果沒有,則this是window 。

<button id='btn1'>測試箭頭函數this_1</button> <button id='btn2'>測試箭頭函數this_2</button> <script type='text/javascript'> let btn1 = document.getElementById(’btn1’); let obj = { name: ’kobe’, age: 39, getName: function () { btn1.onclick = () => { console.log(this);//obj }; } }; obj.getName(); </script>

JavaScript this關鍵字的深入詳解

上例中,由于箭頭函數不會創建自己的this,它只會從自己的作用域鏈的上一層繼承this。其實可以簡化為如下代碼:

let btn1 = document.getElementById(’btn1’); let obj = { name: ’kobe’, age: 39, getName: function () { console.log(this) } }; obj.getName();

那假如上一層并不存在函數,this指向又是誰?

<button id='btn1'>測試箭頭函數this_1</button> <button id='btn2'>測試箭頭函數this_2</button> <script type='text/javascript'> let btn2 = document.getElementById(’btn2’); let obj = { name: ’kobe’, age: 39, getName: () => { btn2.onclick = () => { console.log(this);//window }; } }; obj.getName(); </script>

JavaScript this關鍵字的深入詳解

上例中,雖然存在兩個箭頭函數,其實this取決于最外層的箭頭函數,由于obj是個對象而非函數,所以this指向為Window對象

由于this在箭頭函數中已經按照詞法作用域綁定了,所以, 用call()或者apply()調用箭頭函數時,無法對this進行綁定,即傳入的第一個參數被忽略 :

var obj = { birth: 1990, getAge: function (year) { var b = this.birth; // 1990 var fn = (y) => y - this.birth; // this.birth仍是1990 return fn.call({birth:2000}, year); }};obj.getAge(2018); // 28擴展閱讀

箭頭函數-廖雪峰

JS中的箭頭函數與this

this、apply、call、bind

總結

到此這篇關于JavaScript this關鍵字深入詳解的文章就介紹到這了,更多相關JavaScript this關鍵字內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: JavaScript
相關文章:
主站蜘蛛池模板: 蓄电池回收,ups电池后备电源回收,铅酸蓄电池回收,机房电源回收-广州益夫铅酸电池回收公司 | 破碎机锤头_耐磨锤头_合金锤头-鼎成机械一站式耐磨铸件定制服务 微型驱动系统解决方案-深圳市兆威机电股份有限公司 | 磨煤机配件-高铬辊套-高铬衬板-立磨辊套-盐山县宏润电力设备有限公司 | 行吊_电动单梁起重机_双梁起重机_合肥起重机_厂家_合肥市神雕起重机械有限公司 | 智成电子深圳tdk一级代理-提供TDK电容电感贴片蜂鸣器磁芯lambda电源代理经销,TDK代理商有哪些TDK一级代理商排名查询。-深圳tdk一级代理 | 热回收盐水机组-反应釜冷水机组-高低温冷水机组-北京蓝海神骏科技有限公司 | 不锈钢拉手厂家|浴室门拉手厂家|江门市蓬江区金志翔五金制品有限公司 | 盘扣式脚手架-附着式升降脚手架-移动脚手架,专ye承包服务商 - 苏州安踏脚手架工程有限公司 | 液压中心架,数控中心架,自定心中心架-烟台恒阳机电设计有限公司 行星搅拌机,双行星搅拌机,动力混合机,无锡米克斯行星搅拌机生产厂家 | 螺旋压榨机-刮泥机-潜水搅拌机-电动泥斗-潜水推流器-南京格林兰环保设备有限公司 | 奇酷教育-Python培训|UI培训|WEB大前端培训|Unity3D培训|HTML5培训|人工智能培训|JAVA开发的教育品牌 | 非标压力容器_碳钢储罐_不锈钢_搪玻璃反应釜厂家-山东首丰智能环保装备有限公司 | 内窥镜-工业内窥镜厂家【上海修远仪器仪表有限公司】 | 起好名字_取个好名字_好名网免费取好名在线打分 | 首页-浙江橙树网络技术有限公司| 集装箱箱号识别_自重载重图像识别_铁路车号自动识别_OCR图像识别 | 一体化净水器_一体化净水设备_一体化水处理设备-江苏旭浩鑫环保科技有限公司 | 臭氧发生器_臭氧消毒机 - 【同林品牌 实力厂家】 | 防渗土工膜|污水处理防渗膜|垃圾填埋场防渗膜-泰安佳路通工程材料有限公司 | 柔性测斜仪_滑动测斜仪-广州杰芯科技有限公司 | 涡轮流量计_LWGY智能气体液体电池供电计量表-金湖凯铭仪表有限公司 | 扒渣机厂家_扒渣机价格_矿用扒渣机_铣挖机_撬毛台车_襄阳永力通扒渣机公司 | 番茄畅听邀请码怎么输入 - Dianw8.com | 软膜天花_软膜灯箱_首选乐创品牌_一站式天花软膜材料供应商! | 辐射仪|辐射检测仪|辐射巡测仪|个人剂量报警仪|表面污染检测仪|辐射报警仪|辐射防护网 | 隔离变压器-伺服变压器--输入输出电抗器-深圳市德而沃电气有限公司 | 合肥白癜风医院_合肥治疗白癜风医院_合肥看白癜风医院哪家好_合肥华研白癜风医院 | 精密冲床,高速冲床等冲压设备生产商-常州晋志德压力机厂 | 砍排机-锯骨机-冻肉切丁机-熟肉切片机-预制菜生产线一站式服务厂商 - 广州市祥九瑞盈机械设备有限公司 | 专注提供国外机电设备及配件-工业控制领域一站式服务商-深圳市华联欧国际贸易有限公司 | 坏男孩影院-提供最新电影_动漫_综艺_电视剧_迅雷免费电影最新观看 | 内六角扳手「厂家」-温州市威豪五金工具有限公司 | 东莞ERP软件_广州云ERP_中山ERP_台湾工厂erp系统-广东顺景软件科技有限公司 | 南京泽朗生物科技有限公司| 滚珠丝杆升降机_螺旋升降机_丝杠升降机-德迈传动 | 12cr1mov无缝钢管切割-15crmog无缝钢管切割-40cr无缝钢管切割-42crmo无缝钢管切割-Q345B无缝钢管切割-45#无缝钢管切割 - 聊城宽达钢管有限公司 | 土壤养分检测仪_肥料养分检测仪_土壤水分检测仪-山东莱恩德仪器 大型多片锯,圆木多片锯,方木多片锯,板材多片锯-祥富机械有限公司 | 生产自动包装秤_颗粒包装秤_肥料包装秤等包装机械-郑州鑫晟重工科技有限公司 | 电机铸铝配件_汽车压铸铝合金件_发动机压铸件_青岛颖圣赫机械有限公司 | 飞扬动力官网-广告公司管理软件,广告公司管理系统,喷绘写真条幅制作管理软件,广告公司ERP系统 | 软膜天花_软膜灯箱_首选乐创品牌_一站式天花软膜材料供应商! |