说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

详解 JavaScript 中的 this

HTML文档下载 WORD文档下载 PDF文档下载
JavaScript中的this总是让人迷惑,应该是js众所周知的坑之一。 个人也觉得js中的this不是一个好的设计,由于this晚绑定的特性,它可以是全局对象,当前对象,或者…有人甚至因为坑大而不用this。

其实如果完全掌握了this的工作原理,自然就不会走进这些坑。来看下以下这些情况中的this分别会指向什么:

1.全局代码中的this

alert(x);// 全局变量x值为2

全局范围内的this将会指向全局对象,在浏览器中即使window。

2.作为单纯的函数调用

function fooCoder(x) {this.x = x;}fooCoder(2);alert(x);// 全局变量x值为2

这里this指向了全局对象,即window。在严格模式中,则是undefined。

3.作为对象的方法调用

var name = "clever coder";var person = {name : "foocoder",hello : function(sth){console.log(this.name + " says " + sth);}}person.hello("hello world");

输出 foocoder says hello world。this指向person对象,即当前对象。

4.作为构造函数

new FooCoder();
函数内部的this指向新创建的对象。

5.内部函数

var name = "clever coder";var person = {name : "foocoder",hello : function(sth){var sayhello = function(sth) {console.log(this.name + " says " + sth);};sayhello(}person.hello("hello world");//clever coder says hello world

在内部函数中,this没有按预想的绑定到外层函数对象上,而是绑定到了全局对象。这里普遍被认为是JavaScript语言的设计错误,因为没有人想让内部函数中的this指向全局对象。一般的处理方式是将this作为变量保存下来,一般约定为that或者self:

var name = "clever coder";var person = {name : "foocoder",hello : function(sth){var that = this;var sayhello = function(sth) {console.log(that.name + " says " + sth);};sayhello(sth);}}person.hello("hello world");//foocoder says hello world

6.使用call和apply设置this

person.hello.call(person, "world");
apply和call类似,只是后面的参数是通过一个数组传入,而不是分开传入。两者的方法定义:

call( thisArg [,arg1,arg2,… ] );  // 参数列表,arg1,arg2,...apply(thisArg [,argArray] );     // 参数数组,argArray

两者都是将某个函数绑定到某个具体对象上使用,自然此时的this会被显式的设置为第一个参数。

简单地总结

简单地总结以上几点,可以发现,其实只有第六点是让人疑惑的。

其实就可以总结为以下几点:

  1. 当函数作为对象的方法调用时,this指向该对象。
  2. 当函数作为淡出函数调用时,this指向全局对象(严格模式时,为undefined)
  3. 构造函数中的this指向新创建的对象
  4. 嵌套函数中的this不会继承上层函数的this,如果需要,可以用一个变量保存上层函数的this。

再总结的简单点,如果在函数中使用了this,只有在该函数直接被某对象调用时,该this才指向该对象。

obj.foocoder();foocoder.call(obj, ...);foocoder.apply(obj, …);

更进一步

我们可能经常会写这样的代码:

$("#some-ele").click = obj.handler;
如果在handler中用了this,this会绑定在obj上么?显然不是,赋值以后,函数是在回调中执行的,this会绑定到$(“#some-div”)元素上。这就需要理解函数的执行环境。本文不打算长篇赘述函数的执行环境,可以参考《javascript高级程序设计》中对执行环境和作用域链的相关介绍。这里要指出的时,理解js函数的执行环境,会更好地理解this。

那我们如何能解决回调函数绑定的问题?ES5中引入了一个新的方法,bind():

fun.bind(thisArg[, arg1[, arg2[, ...]]])thisArg

当绑定函数被调用时,该参数会作为原函数运行时的this指向.当使用new 操作符调用绑定函数时,该参数无效.

arg1, arg2, ...
当绑定函数被调用时,这些参数加上绑定函数本身的参数会按照顺序作为原函数运行时的参数.

该方法创建一个新函数,称为绑定函数,绑定函数会以创建它时传入bind方法的第一个参数作为this,传入bind方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数.

显然bind方法可以很好地解决上述问题。

$("#some-ele").click(person.hello.bind(person));//相应元素被点击时,输出foocoder says hello world

其实该方法也很容易模拟,我们看下Prototype.js中bind方法的源码:

Function.prototype.bind = function(){  var fn = this, args = Array.prototype.slice.call(arguments), object = args.shift();  return function(){    return fn.apply(object,      args.concat(Array.prototype.slice.call(arguments)));  };};

明白了么?

相信看完全文以后,this不再是坑~

美FDA通过搜索引擎和社交平台预警药品副作用 挖坟三星“眼球追踪技术”背后的技术团队 为什么开发者热衷在Stack Overflow上查阅API文档? Facebook推新News Feed 欲造就“个性化报纸” 女神程序员的一天:暴力测试social爬虫代码 2013IBM云存储路线图:更快,更简单,更安全 二战大数据故事:数学家、物理学家、概率论击败德国潜艇 软件定义网络服务商Pertino B轮融资2000万 Scringo社交组件,让你的应用“热闹”起来! Android开发必备:Eclipse 4.2 SR2版本发布 32场!2013年360HTML5校园行首站告捷 移动周报:不做内容,只钻技术的快播 一周消息树:中国开源发展缓慢的“病因” 百度应用引擎BAE正式开放 新增支持Node.js CloudVelocity,下一个VMware? Buffer创始人谈开发:先验证,后编程! 谷歌可穿戴式产品再度来袭:会说话的鞋子 未来Chrome OS或取得Android般成功 云落地@北京,北京市北斗公共平台或开放API? GitHub再遭攻击 主要服务中断约一小时 移动开发者将有望拥有.app域名使用权 微信将推“游戏中心”?移动互联网入口圈地加剧 美国航空公司首次开放API 并举办“黑客马拉松”编程大赛 谷歌数据中心设计的10条“黄金法则” GitHub时代:为什么我们都在开源 VMware发布Horizon Suite 三款应用打包折扣低 TOP30+应用排行榜:二月份国内外综合榜单 开源是否意味着不需要负任何责任? 微软年度科技展 酷炫技术知多少 图解Hadoop生态系统 HTML5并不给力 微软IE10又默认启用Flash vb开发进程?Hook技术? 所谓的基础的是什么 识别上网状态问题,请教各位大虾。 再问:请问可以在applet中使用MenuBar吗?(昨天的已经给分了) 统计一下win2000下可以玩的游戏 *.chm文件能作在线帮助吗?在窗体的helpfile、和helpcontext如何设置??? 如何根据列名用object来取出字段,急!!!! 关于箭头在数据窗口移动的问题? 再问个菜鸟问题,showmodaldialog的title怎样控制 javascript中如何取整? ALT和MFC的区别是什么?? 试用DELPHI6,BUG太多了! 我是新手,请问在delphi5中如何建库(orcle和sybase)? 问一个比较弱智的问题 js文件里如何使用另一个js文件里的函数30? 哪位大虾知道可以在哪里下载mpeg-1的codec,谁先告诉有效地址谁先得分!(不给分是小狗!) 可能很菜的问题,送分的问题!! 一个关于CDaoTableDefInfo的问题 ado的问题??求救!!!高分!!! 有关代码重用的问题,对Form的继承。 一个关于CString.Format的问题 学习编程时学图算法怎么学好? 一个很简单的CREATE TABLE语句为什么出错呢?向大家请教! jbuilder5运行需要最低配置 ,傻傻的问 Delphi6的盗版已经到了@_@ 喂,为什么我提问只能给最多37分,原先可比这要多的多 一个关于派生类的问题 关于页面关闭的问题 用new JTalbe(10, 20)创建了一个table,如何设置该table列(column)的宽度 请教一个关于用VC6开发outlook\exchange的问题。急!急! 时间服务器 请问一下,用DBM,如果用户注册的数量多了以后,程序的速度很一般的文本速度比较哪个快 纯数学问题:如何求模逆元? VB中实现进程间通信的方法?VB中的CallWindowProc的用法?VB中如何发送自定义的消息? 请问哪里能免费下载BCB5?下载多长时间没有关系,只要能够正确使用就可以了。 怎样得知CListCtrl中当前选项? 我想从WINME中自带的一个驱动程序提取出来在WIN97中安装,请问应如何做? 菜问题(2) 请教:为何数据库数据无法在网页上显示? CEditView 一定要override onChange function(ON_CONTROL_REFLECT(EN_CHANGE, OnChange))????;否则input 时不我待会错??? 请教:不通过页面,用VB如何得知来访者的IP? 如何将vcd转化为real的格式???????????急!!!!!!!!!!!!!! 对DMO播放内存MPEG2数据没有头绪,谁能给点提示? 支持bestbestbest!!!!!!!!!!!! 如何在win98下使用EJB? applet 可以打开到一个server的socket么 谁知道国内哪有下载jdk1.4,Thanks! 如何配置For Oracle8i 的ODBC? 请教如何动态改变窗口大小 弟兄们救命啊!!!rational rose中mdl的导出 Jbuilder5.rar的密码? 某中学为帮助贫困山区的失学儿童重返课堂,要在全校开展一次献爱心捐款、捐物、捐书活动.请你为这次活动要求.运用对联,有文采并体现人文关怀,每条不少于十字 六年级同学向汶川大地震灾区的小朋友捐款3000元 五年级与六年级捐款数的比是4;5 5年纪比四年级少1/6五年级捐款多少?四年级捐款多少?某工厂女职工人数的6/7 正好是男职工人数的3/4 男职工24 学校开展“爱心捐款”,六年级同学捐款1485元五年级同学捐款的钱数比六年级少五分之一,五年级捐款多少元 派立方木门发起的爱心捐书活动要捐多少本书啊?已经报名参加了书香暖童心活动了,想问下这个活动捐书有没有最低限制啊? 四川汶川地震发生后,实验小学一年级小朋友纷纷向灾区捐出自己的零花钱,已知一班所捐的钱数是二班、三班两个班和的2/3,二班捐的钱数是一班、三班和的2/5,又已知一班和三班所捐的钱数之 学校把360本科技书分配给甲、乙、丙三个班,甲班的2分之1等于乙班的3分之1,等于等于丙班的4分之1,甲、乙、丙三个班各分得多少本?要算式 在为西部的捐书活动中,六年级五个班共捐书630本,其中一班捐书140本,二班比一班少捐10本,三班捐的本数是全年级的百分之20,四班于五班捐的本数比是6:7,四班捐了多少本? 实验小学为灾区小朋友捐款一班50人共捐款249元.二班48人平均捐款四元平均两个班每人捐款多少元? 七年级甲、乙、丙三个班分别想贫困地区的学生捐赠图书,已知这三个班级捐赠图书的册数为7:8:9.问(1)若三个班级捐赠图书捐赠图书2112册,试问这个三个班级各捐赠图书多少侧?(2)若甲、 班上要进行一次捐书活动,请在班上做一次捐书倡议的发言 实验小学为四川灾区小朋友捐款,五年级一班50人,共捐款290元,五年级二班有40人,平均每人捐款4元,两个班平均每人捐款多少元/ 甲乙丙三位同学向贫困地区的少年儿童捐赠图书的册数之比是5;6;9,如果甲丙两位同学捐书册书的和是.甲乙丙三位同学向贫困地区的少年儿童捐赠图书的册数之比是5;6;9,如果甲丙两位同学捐书 某校初三一班和二班向贫困学生捐书活动,两个班捐书280册,二班捐的是一班1.8倍二班人数是一班人数1.2倍,二班平均每人比一班多捐一本书,求一班和二班各有多少人 某小学为玉树地震灾区捐款,已知五年级是六年级的3分之2,六年级比五年级多捐0.36万元,五年级捐款()万算式是什么! 甲、乙、丙三位同学向贫困地区的少年儿童捐赠图书,已知这三位同学捐赠图书册数的比是5:6:9.(1甲、乙、丙三位同学向贫困地区的少年儿童捐赠图书,已知这三位同学捐赠图书册数的比是5:6: 光明小学原计划向山区捐书1200册,实际捐书比计划多10%,实际捐书多少册? 光明小学五六年级学生向四川省汶川县灾区捐款数额的比是3:4,五年级一共捐款2400元,六年级一共捐款多少元光明小学五六年级学生向四川省汶川县灾区捐款数额的比是3:4,六年级一共捐款多少 光明小学在六一前开展了为贫困地区的“希望小学”捐赠图书的活动.六一节一大早,满载的图书汽车从校园出了.4小时过去了,校长打电话问随行的大队长,询问有没有到达,大队长说:我们4小 的件数正好是全校的25%,全校共做好事多少件?学校开展学雷锋活动,四年级做了21件好事,比五年级少30%,相当于六年级的75%,六年级的件数正好是全校的25%,全校共做好事多少件? 某小学为玉树地震灾区举行赈灾捐款活动,已知五年级四个班平均每班捐款845元,六年级六个班共捐款7200元,那么五,六年级平均每班捐款多少元 光明小学在六一前开展了为贫困地区的希望小学捐赠图书的活动,61节一大早,满载着图书的汽车从校园出发了4小时过去了,校长拨通了随行大队辅导员的手机,询问有没有到达.大队辅导员说: 学校开展学雷锋活动,四年级做了21见好事,比五年极少30%,相当于六年级的75%,六年级做的件数正好是全校的25%,全校共做好事多少件? 7年级学生为汶川地震灾区捐款共131元,正好是平均每人2元还多35元,则该班学生有多少人? 六年级三个班共有120,六一班是六二班人数的百分之90,六三班是六二班人数百分之110.求这三个各有多少人? 四年级做了21件好事,比5年级少30%,相当于六年级的75%,六年级做的件数正好是全校的25全校共做好事多少件? 5年级学生共为地震灾区捐款900元,其中五年级学生捐款数是四年级的1.5倍,五年级学生捐款多少元? 环保活动中六一班,六二班,六三班,捡塑料袋的比是5:3:4,六一班比六二班多拣了120个,六三班拣了多少 育红小学五、六年级为贫困山区学生捐书660册,其中五年级3个班,每个班平均捐120册.六年级有2个班,平均每个班捐书多少册?用方程解. 深圳某小学在“献爱心—为四川地震灾区捐款”活动中,六年级四个班共捐款4000元.其中一班捐款1000元,二班捐款数是六年级捐款总数的20%,三班与四班捐款数比是5:6求四班捐款多少元? 已知六一班和六二班共81人,六二班和六三班共83人,六三班和六四班共86人,六一班比六一班比六四班多2人,每班各有多少人 2013年4月20日8:02,四川省雅安市芦山县发生7.0级大地震,许多公路由于地震引起的山体滑坡 在"爱心捐款"活动中,五年级同学捐款258元,5倍少12元,2倍多6元. 六一班比六二班多18人,六三班比六二班少2人,六一班与六二班的人数比是5:8,三个班各多少人 数学题:2013年4月20日8时2分在四川省雅安市芦山县发生7.0级地震,有1.8万人等待安置,各地人民纷纷捐款灾区.某市一企业在得知灾区急需帐篷后立即与厂家联系购买帐篷送往灾区.已知用9万元 某小学在爱心捐款活动中,五年级共捐款1038元,2倍少30元,该校这次爱心捐款五、六年级共捐款多少元? 六一班和六二班为四川地震的灾区共捐款8800元,已知六一班比六二班多捐20%,问两个班各捐多少元? 北京时间2013年4月20日8时2分在四川省雅安市芦山县发生7.0级地震北京时间2013年4月20日8时2分在四川省雅安市芦山县(北纬30.3,东经103.0)发生7.0级地震,震源深度13公里. 育红小学三、四、五、六年级参加献爱心捐款活动.其中三年级捐了总数的五分之一,四年级捐了总数的25%,五、六年级捐款总数的比是5:6, 为地震灾区捐款,六一班捐款550元,六二捐款440元...接上——后来六二班王小明又捐了一些钱,这时六一和六二捐款数的比是11:9,王小明又捐了多少? 2013年4月20号,四川省雅安发生了7.0级地震,为了抢救伤员,一架救援直升机从芦山县某镇A地起飞,2013年4月20日,四川省雅安发生了7.0级地震,为了抢救伤员,一架救援直升机从芦山县某镇A地起飞,运 育红小学三、四、五六年级参加献爱心捐款活动.其中三年级捐了总数的1/5育红小学三、四、五、六年级参加献爱心捐款活动,其中三年级捐了总数的五分之一,四年级捐了总数的25%, 请用脱式计算下题:(1) 园林局为了绿化公路,在一段公路的两边每隔4米栽一棵树,一共栽树74棵,现在要改每隔6米栽一棵树.那么,不移栽的树有多少棵?(2)一台机器3小时耕地15公顷,照这样计算 关于雅安大地震的作文450字(多多益善) 三四五六年级参加爱心捐款,其中三年级捐了总数的五分之一,四年级捐了总数的百分之二十五,E三四五六年级参加爱心捐款,其中三年级捐了总数的五分之一,四年级捐了总数的百分之二十五,五 园林局为了绿化公路,在一段公路的两旁每隔4米栽一棵树,一共栽树74棵,现在要改成每隔6米栽一棵树.那么,不移栽的树有多少? 雅安大地震令人感动的事 注意是(子母事件) 作文500字 在一次献爱心捐款的活动中,1班捐款是2班的2分之1,2班捐款是3班的3分之1,3班捐款是4班的4分之1,4个班共捐了7920元,1班捐了多少元 为防沙固土,市园林局沿着一条公路栽树第一棵栽在路的始端,以后每隔50米栽一棵树,要求在路的末端栽一棵,这样就缺少21课,如果每隔55米栽一棵,要求在路的末端栽一棵,这样只缺少1课树,求树 512汶川大地震作文的开头怎么写 在献爱心捐款活动中,光明小学四年级捐款180元,比五年级少捐25%,kuai kuai kuai kuai kuai!xie xie xie xie xie xie 为放沙固土,市园林局沿着一条公路栽树,第一棵栽在路的始端,以后每隔50米栽一棵树,要求在路的末端栽一棵树,这样就缺少21棵,如果每隔55米栽一棵,要求在路的末端栽一棵,这样只缺少1棵树.求 谁有众志成城的(关于日本大地震的)作文开头 在爱心捐款活动中,昆明小学四年级捐款180元比五年级烧捐125元, 在一段公路的两边每隔4米栽一棵树,一共栽树74棵,现在要改每隔6米载一棵树.那么,不栽的树有多少棵?帮帮我吧~教科书的答案是26棵,不知你们怎样做~~~~谢谢!不是不栽,而是不移栽~~~~~sorry~~~拜 胜利小学学生开展支援灾区捐书活动,六年级捐书90本,占全校捐书总数的4分之1,全校捐书多少本? 关于雅安地震的作文开头结尾 在献爱心捐款活动中,爱心小学四年级捐款220元,比五年级少捐25%, 某班开展贫困山区学校捐书活动,捐的书比平均每人捐3本多21本,比平均每人捐4本少27本,有多少名学生算式 2013年4月20日8时02分,四川省雅安市芦山县发生7.0级强烈地震.某市接到上级通知,立即派出甲、乙两个抗震救灾小组同时乘车沿同一路线赶赴距出发点480千米的灾区.图中的折线、线段分别表示 在献爱心捐款活动中光明小学四年级捐献180元五年级比四年级少捐献了百分之25四五年级一共捐了多少元
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn