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

您的位置:首頁技術(shù)文章
文章詳情頁

如何使用Javascript中的this關(guān)鍵字

瀏覽:2日期:2023-06-20 16:00:04

一、基本的:

function doSomething(){alert(this.id);}alert(window.doSomething);//證明了doSomething是屬于window的doSomething();//undefinedwindow.onload = function(){document.getElementById('div2').onclick = doSomething;//div2document.getElementById('div3').onclick = function(){doSomething();}//undefined}

1、對(duì)于doSomething這個(gè)函數(shù):

function doSomething(){alert(this.id);}

這個(gè)函數(shù)是全局函數(shù),這種全局函數(shù)實(shí)際上是屬于window的(可以通過window.doSomething來訪問),如果直接調(diào)用,那么根據(jù)“this always refers to the “owner” of the function we’re executing”,那么函數(shù)中的this就是window,但是window沒有id屬性,所以顯示“undefined”;

2、在html元素中這樣調(diào)用

<div onclick='doSomething();'>div1</div>

這時(shí)也會(huì)顯示“undefined”,這就相當(dāng)于如下代碼:

document.getElementById('div1').onclick = function(){doSomething();}

當(dāng)點(diǎn)擊div1時(shí),調(diào)用屬于window的doSomething函數(shù),所以也是顯示“undefined”;

3、通過js來綁定事件,在div2載入過后:

document.getElementById('div2').onclick = doSomething;

當(dāng)點(diǎn)擊div2時(shí),顯示“div2”,因?yàn)樵诮odiv2的onclick賦值,是將doSomething拷貝了一次,這時(shí)拷貝的這個(gè)函數(shù)是屬于div2的了,跟屬于window的doSomething沒有任何關(guān)系了。點(diǎn)擊div2時(shí),就會(huì)觸發(fā)屬于div2的doSomething,這里的this就是指div2。

二、attachEvent和addEventListener 

attachEvent是在ie中綁定事件的方法,會(huì)將相應(yīng)函數(shù)拷貝到全局(即響應(yīng)函數(shù)的owner為window),但是在DOM標(biāo)準(zhǔn)中,addEventListener綁定的事件時(shí)拷貝的響應(yīng)函數(shù)的owner為事件所綁定的對(duì)象

function doSomething(){alert(this.id);alert(this == window);}window.onload = function(){var div1 = document.getElementById('div1');if(div1.attachEvent){div1.attachEvent('onclick',doSomething);document.body.appendChild(document.createTextNode('attachEvent'));}else if(div1.addEventListener){div1.addEventListener('click',doSomething,false);document.body.appendChild(document.createTextNode('addEventListener'));}else{div.onclick = doSomething;}}

對(duì)于函數(shù)doSomething

function doSomething(){alert(this.id);alert(this == window);}

1、使用attachEvent綁定到div1的click事件上,doSometing會(huì)被復(fù)制到window,這時(shí)doSomething里面的this指的是window,點(diǎn)擊div1時(shí)會(huì)顯示“undefined”和“true”

2、使用addEventListener綁定div1的click事件,這時(shí)將doSomething拷貝,這個(gè)拷貝過后的函數(shù)是屬于div1的,所以點(diǎn)擊div1時(shí)會(huì)顯示“div1”和“false”,看如下代碼

var obj = new Object();obj.color = 'black';obj.showColor = function(){alert(this.color);alert(this == window);}obj.showColor();var div1 = document.getElementById('div1');div1.attachEvent('onclick',obj.showColor);

此時(shí)點(diǎn)擊div1的時(shí)候,會(huì)顯示“undefined”和“true”,如果attachEvent僅僅是引用obj.showColor的話,那么this還是應(yīng)該指的是obj,但是實(shí)際上這里this指的是window,所以我認(rèn)為這里不是引用,而是拷貝到全局的。

三、關(guān)于對(duì)象冒充的繼承方式 

1、new與不new的區(qū)別

對(duì)于如下function

function ClassA(sColor){this.color = sColor;this.sayColor = function(){alert(this.color);}}

這是一個(gè)類還是一個(gè)函數(shù)?隨你而定!

如果你認(rèn)為這是一個(gè)函數(shù),那么我們可以這樣來調(diào)用它:

ClassA('red');

“red”是傳遞的一個(gè)參數(shù),ClassA中的this指的是當(dāng)然就是指的window了,所以現(xiàn)在window有了color屬性和sayColor方法,并且color有“red”這個(gè)值。

這是調(diào)用sayColor或者window.sayColor都可以顯示“red”;

window.sayColor();

如果你認(rèn)為這是一個(gè)類,那么我們應(yīng)該這樣使用它:

var obj = new ClassA('red');

new這個(gè)關(guān)鍵詞的出現(xiàn)讓上面這一句代碼增加了不少內(nèi)容:首先,創(chuàng)建一個(gè)Object實(shí)例,然后,將ClassA中的this指向創(chuàng)建的這個(gè)Object中,最后返回這個(gè)Object,所以返回的這個(gè)Object就賦值給了obj。所以我們可以說this指向的是obj,obj擁有了color屬性和sayColor方法,并且color屬性值為“red”。

2、函數(shù)的owener

function showId(){alert(this.id);}window.onload = function(){var div1 = document.getElementById('div1');div1.onclick = showId;div1.show = showId;div1.show();var obj = new Object();obj.id = 'obj';obj.show = showId;obj.show();}

我們可以將showId這個(gè)函數(shù)賦值給click事件,也可以賦值給任何一個(gè)對(duì)象的任何一個(gè)屬性,這是也會(huì)拷貝showId這個(gè)方法的,所以我們?cè)谡{(diào)用div1.show方法時(shí),this是指向div1的,在調(diào)用obj.show時(shí),this指向的是obj的。

3、對(duì)象冒充的原理

下面的代碼是通過對(duì)象冒充方法實(shí)現(xiàn)的繼承

function ClassA(sColor){this.color = sColor;this.sayColor = function(){alert(this.color);}}function ClassB(sColor,sName){this.newMethod = ClassA;this.newMethod(sColor);delete this.newMethod;this.name = sName;this.sayName = function(){alert(this.name);}}var objB = new ClassB('color of objB','name of objB');objB.sayColor();

objB是ClassB的一個(gè)實(shí)例,objB是如何擁有color屬性和sayColor方法的呢?

首先從實(shí)例化的代碼看起:

var objB = new ClassB('color of objB','name of objB');

這里ClassB是個(gè)類,ClassB中的this當(dāng)然就是指的objB這個(gè)對(duì)象;

在ClassB中,前三行代碼會(huì)用到ClassA,這時(shí)就把ClassA看作一個(gè)函數(shù),而不是類。

我們?nèi)绻苯诱{(diào)用ClassA這個(gè)函數(shù),那么很顯然,ClassA中的this指的就是window對(duì)象了,所以我們先將ClassA拷貝到objB的newMethod這個(gè)屬性中(this.newMethod = ClassA),

然后再調(diào)用this.newMethod,這是這個(gè)方法的owener明顯的已經(jīng)成了this,而ClassB中的this在當(dāng)前指的是objB,所以此時(shí)ClassA中(嚴(yán)格的說是newMethod中,因?yàn)檫@是拷貝過后的,跟ClassA已經(jīng)是兩個(gè)方法了)的this就是指的objB,這樣在通過newMethod的調(diào)用,就給objB賦值了color屬性和sayColor方法。用call和apply方法來實(shí)現(xiàn)繼承實(shí)際上也是一個(gè)原理,call和apply可以看作是改變方法的owner的方法,而這里ClassB中的前三句代碼也就是起這個(gè)作用的。

四、prototype1.6中的Class.create

prototype1.6中的Class.create方法大致如下:

var Class = {create: function() {//function klass() {this.initialize.apply(this, arguments);}//for (var i = 0; i < properties.length; i++)klass.addMethods(properties[i]);//return klass;}};

在使用的時(shí)候是這樣的:

var Person = Class.create({initialize:function(name){this.name = name;},say:function(message){alert(this.name + ':' + message);}});var aPerson = new Person('name1');aPerson.say('hello1');

Person實(shí)際上是通過Class.create這個(gè)方法所返回的klass(klass是Class.create中的局部變量,是一個(gè)function),Class.create所傳遞的參數(shù)(initialize方法和say方法)傳遞到create方法中的properties數(shù)組中并且通過addMethods方法讓klass的prototype擁有這些方法。那么最關(guān)鍵的地方也是最難以理解的地方是:klass中的this究竟是指的是什么。仔細(xì)想一想就不難得到答案,Person實(shí)際上就是klass,而我們?cè)趯?shí)例化Person對(duì)象的時(shí)候,是用了new關(guān)鍵詞的:

var aPerson = new Person('name1');

這就等價(jià)于

var aPerson = new klass('name1');

雖然klass在外面不能被訪問到,但是這樣能很輕易的說明問題,klass是一個(gè)類而不是簡(jiǎn)單的一個(gè)函數(shù)(我們看作如此,因?yàn)橛昧薾ew關(guān)鍵字),那么klass中的this就指的是聲明的實(shí)例,在這里就是aPerson,aPerson通過klass的prototype能夠擁有initialize方法和say方法,在new的過程中,也會(huì)執(zhí)行klass中的代碼,所以initialize在實(shí)例化的時(shí)候會(huì)執(zhí)行,即構(gòu)造函數(shù)。(在klass里兩個(gè)this都是指的aPerson,為什么還要通過apply調(diào)用一次呢?這主要是為了傳遞構(gòu)造函數(shù)的參數(shù),用apply方法可以將數(shù)目不定的多個(gè)參數(shù)通過數(shù)組方便的傳到initialize方法中去。)

五、再分析幾個(gè)例子

從別的文章里看到的例子,我在這里分析一下:

1、運(yùn)行如下代碼

function OuterFoo(){this.Name = ’Outer Name’;function InnerFoo(){var Name = ’Inner Name’;alert(Name + ’, ’ + this.Name);}return InnerFoo;}OuterFoo()();

所顯示的結(jié)果是“Inner Name, Outer Name”

OuterFoo是一個(gè)函數(shù)(而不是類),那么第一句

this.Name = ’Outer Name’;

中的this指的是window對(duì)象,所以O(shè)uterFoo()過后window.Name = ‘Outer Name’;

并且將InnerFoo返回,此時(shí)InnerFoo同樣是一個(gè)函數(shù)(不是類),執(zhí)行InnerFoo的時(shí)候,this同樣指window,所以InnerFoo中的this.Name的值為”O(jiān)uter Name”(window.Name充當(dāng)了一個(gè)中轉(zhuǎn)站的角色,讓OuterFoo能夠向InnerFoo傳遞“Outer Name”這個(gè)值),而Name的值即為局部變量”Inner Name”

2、運(yùn)行如下代碼

function JSClass(){this.m_Text = ’division element’;this.m_Element = document.createElement(’DIV’);this.m_Element.innerHTML = this.m_Text;if(this.m_Element.attachEvent)this.m_Element.attachEvent(’onclick’, this.ToString);else if(this.m_Element.addEventListener)this.m_Element.addEventListener(’click’, this.ToString,false);elsethis.m_Element.onclick = this.ToString;}JSClass.prototype.Render = function(){document.body.appendChild(this.m_Element);}JSClass.prototype.ToString = function(){alert(this.m_Text);alert(this == window);}window.onload = function(){var jc = new JSClass();jc.Render();jc.ToString();}

點(diǎn)擊“division element”會(huì)顯示“undefined”,在ie下還要顯示“true”,其他瀏覽器中還要顯示“false”。

實(shí)例聲明和調(diào)用實(shí)例方法都沒什么可說的,元素的click事件的綁定到了一個(gè)實(shí)例的方法,那么通過addEventListener綁定到的方法是拷貝過后的,所以this指的是html元素,這個(gè)元素沒有m_Text屬性(m_Text屬性是屬于JSClass的實(shí)例的,即屬于jc的),所以點(diǎn)擊元素顯示undefined,attachEvent綁定的事件會(huì)將函數(shù)復(fù)制到全局,此時(shí)this指的是window對(duì)象,點(diǎn)擊元素也會(huì)顯示“undefined”。只有在調(diào)用jc.ToString()方法是,this指的是jc這個(gè)對(duì)象,因?yàn)閖c擁有m_Text,所以能夠顯示“division element”。

六、總結(jié)

怎樣在一個(gè)代碼環(huán)境中快速的找到this所指的對(duì)象呢?我想要注意以下三個(gè)方面:

1、 要清楚的知道對(duì)于函數(shù)的每一步操作是拷貝還是引用(調(diào)用)

2、 要清楚的知道函數(shù)的擁有者(owner)是什么

3、 對(duì)于一個(gè)function,我們要搞清楚我們是把它當(dāng)作函數(shù)使用還是在當(dāng)作類使用

補(bǔ)充:

1.在實(shí)例和類上都可以直接定義函數(shù)

2.不能在實(shí)例上使用prototype定義函數(shù),只能在類上使用prototype定義函數(shù)

3.類上直接定義的函數(shù)不能使用this訪問對(duì)象的屬性

4.在類的prototype上建立的函數(shù)可以用this,在類內(nèi)部定義的函數(shù)可以使用this,在對(duì)象實(shí)例上建立的函數(shù)額可以this

window.alert=function (msg){document.write(msg+'<br>');}function say(){this.f='props';this.func3=function(){alert('f3,'+this.f);}}say.func1=function(){alert('func1,'+this.f);}; //Error,類上直接定義的函數(shù),不能使用thissay.prototype.func2=function(){alert('func2,'+this.f);}say.func1();(new say()).func2();say.func2(); //Error, 在用prototype定義的函數(shù),必須實(shí)例化對(duì)象才能調(diào)用say.func3(); //Error,在類上定義的函數(shù),必須實(shí)例化才能調(diào)用(new say()).func3();var obj={fld1:10,func1:function(msg){alert(msg);},func4:function(){alert(this.fld1);}}obj.prototype.func=function(){alert('func');}; //Error 實(shí)例對(duì)象上不能使用prototype定義對(duì)象obj.func2=function(){alert('func2,'+this.fld1);}; //ok,實(shí)例上直接定義的函數(shù)可以使用this,訪問對(duì)象的屬性alert(obj.fld1);obj.func1('func1');obj.func2();obj.func4();

以上就是如何使用Javascript中的this關(guān)鍵字的詳細(xì)內(nèi)容,更多關(guān)于js this關(guān)鍵字的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: JavaScript
相關(guān)文章:
主站蜘蛛池模板: ERP企业管理系统永久免费版_在线ERP系统_OA办公_云版软件官网 | 台式低速离心机-脱泡离心机-菌种摇床-常州市万丰仪器制造有限公司 | 成都离婚律师|成都结婚律师|成都离婚财产分割律师|成都律师-成都离婚律师网 | 蓝米云-专注于高性价比香港/美国VPS云服务器及海外公益型免费虚拟主机 | 德州万泰装饰 - 万泰装饰装修设计软装家居馆| 不干胶标签-不干胶贴纸-不干胶标签定制-不干胶标签印刷厂-弗雷曼纸业(苏州)有限公司 | 中高频感应加热设备|高频淬火设备|超音频感应加热电源|不锈钢管光亮退火机|真空管烤消设备 - 郑州蓝硕工业炉设备有限公司 | 软文发布-新闻发布推广平台-代写文章-网络广告营销-自助发稿公司媒介星 | 海鲜池-专注海鲜鱼缸、移动海鲜缸、饭店鱼缸设计定做-日晟水族厂家 | 拉伸膜,PE缠绕膜,打包带,封箱胶带,包装膜厂家-东莞宏展包装 | 超声波焊接机,振动摩擦焊接机,激光塑料焊接机,超声波焊接模具工装-德召尼克(常州)焊接科技有限公司 | 泉州陶瓷pc砖_园林景观砖厂家_石英砖地铺石价格 _福建暴风石英砖 | 东莞市天进机械有限公司-钉箱机-粘箱机-糊箱机-打钉机认准东莞天进机械-厂家直供更放心! | T恤衫定做,企业文化衫制作订做,广告T恤POLO衫定制厂家[源头工厂]-【汉诚T恤定制网】 | 幂简集成 - 品种超全的API接口平台, 一站搜索、试用、集成国内外API接口 | 「阿尔法设计官网」工业设计_产品设计_产品外观设计 深圳工业设计公司 | 食安观察网| 安平县鑫川金属丝网制品有限公司,声屏障,高速声屏障,百叶孔声屏障,大弧形声屏障,凹凸穿孔声屏障,铁路声屏障,顶部弧形声屏障,玻璃钢吸音板 | 北京浩云律师事务所-企业法律顾问_破产清算等公司法律服务 | 温室大棚建设|水肥一体化|物联网系统 | 电渗析,废酸回收,双极膜-山东天维膜技术有限公司 | 生物制药洁净车间-GMP车间净化工程-食品净化厂房-杭州波涛净化设备工程有限公司 | 高扬程排污泵_隔膜泵_磁力泵_节能自吸离心水泵厂家-【上海博洋】 | UV固化机_UVLED光固化机_UV干燥机生产厂家-上海冠顶公司专业生产UV固化机设备 | 螺旋丝杆升降机-SWL蜗轮-滚珠丝杆升降机厂家-山东明泰传动机械有限公司 | 伊卡洛斯软装首页-电动窗帘,别墅窗帘,定制窗帘,江浙沪1000+别墅窗帘案例 | 科箭WMS仓库管理软件-TMS物流管理系统-科箭SaaS云服务 | 电子万能试验机_液压拉力试验机_冲击疲劳试验机_材料试验机厂家-济南众标仪器设备有限公司 | 二手色谱仪器,十万分之一分析天平,蒸发光检测器,电位滴定仪-湖北捷岛科学仪器有限公司 | 冷藏车-东风吸污车-纯电动环卫车-污水净化车-应急特勤保障车-程力专汽厂家-程力专用汽车股份有限公司销售二十一分公司 | 悬浮拼装地板_幼儿园_篮球场_悬浮拼接地板-山东悬浮拼装地板厂家 | 合肥地磅_合肥数控切割机_安徽地磅厂家_合肥世佳电工设备有限公司 | 长沙中央空调维修,中央空调清洗维保,空气能热水工程,价格,公司就找维小保-湖南维小保环保科技有限公司 | 成都热收缩包装机_袖口式膜包机_高速塑封机价格_全自动封切机器_大型套膜机厂家 | 隧道风机_DWEX边墙风机_SDS射流风机-绍兴市上虞科瑞风机有限公司 | 棉服定制/厂家/公司_棉袄订做/价格/费用-北京圣达信棉服 | 连续油炸机,全自动油炸机,花生米油炸机-烟台茂源食品机械制造有限公司 | 散热器-电子散热器-型材散热器-电源散热片-镇江新区宏图电子散热片厂家 | 实验室pH计|电导率仪|溶解氧测定仪|离子浓度计|多参数水质分析仪|pH电极-上海般特仪器有限公司 | 吹田功率计-长创耐压测试仪-深圳市新朗普电子科技有限公司 | 上海刑事律师|刑事辩护律师|专业刑事犯罪辩护律师免费咨询-[尤辰荣]金牌上海刑事律师团队 |