JS this的指向及其应用
【例 1】this 指向示例。
!doctype html html head meta charset= utf-8 title this指向示例 /title script window.onload = function (){ function fn1(){ alert(this); function fn2(obj){ alert(obj); var aBtn = document.getElementsByTagName( input //使用标签名获取所有按钮 fn1(); //① 直接调用fn1函数 aBtn[0].onclick = fn1; //② 通过按钮1的单击事件来调用fn1函数 aBtn[1].onclick = function (){ fn1(); //③ 在匿名函数中调用 aBtn[2].onclick = function (){ fn2(this); //④ 在匿名函数中调用 /script /head body input type= button value= 按钮1 / input type= button value= 按钮2 / input type= button value= 按钮3 / /body /html
上述代码中,① 处代码是直接调用 fn1 函数,该代码等效于 window.fn1(),即调用当前函数 fn1 是 window 对象,所以执行 fn1 函数后输出的 this 为 window 对象,结果如图 1 所示。
![直接调用fn1的结果](http://ytso-blog-oss-img.oss-cn-beijing.aliyuncs.com/wp-content/uploads/2021/07/20/20210720_60f643c5701da.jpg)
图 1:直接调用 fn1 的结果
② 处代码是通过按钮 1 的单击事件来调用 fn1 函数,所以此时调用 fn1 函数的是 aBtn[0],因此执行 fn1 函数后输出的 this 为按钮对象,结果如图 2 所示。
![单击按钮1的结果](http://ytso-blog-oss-img.oss-cn-beijing.aliyuncs.com/wp-content/uploads/2021/07/20/20210720_60f643c57d271.jpg)
图 2:单击按钮 1 的结果
③ 处代码是在匿名函数中调用,而匿名函数又是通过按钮2 的单击事件来调用,即对于按钮 2 来说,匿名函数为当前函数,执行当前函数体时会调用 fn1,此时 fn1 的调用等效于 window.fn1(),对于 window 对象来说,fn1 为当前函数,所以执行 fn1 后输出的 this 为 window 对象,结果如图 3 所示。
![单击按钮2的结果](http://ytso-blog-oss-img.oss-cn-beijing.aliyuncs.com/wp-content/uploads/2021/07/20/20210720_60f643c596059.jpg)
图 3:单击按钮 2 的结果
④ 处代码和 ③ 处代码一样,也是由匿名函数调用,但不同的是,fn2 函数的参数是在按钮3 的当前函数,即匿名函数中指定,所以 fn2 函数中的参数 this 指向的是按钮 3,运行结果如图 4 所示。
![单击按钮3的结果](http://ytso-blog-oss-img.oss-cn-beijing.aliyuncs.com/wp-content/uploads/2021/07/20/20210720_60f643c5adb7f.jpg)
图 4:单击按钮3的结果
从示例 1 中可以看到,this 在 JS 程序中是用来指向当前对象的,但在不同情况下,this 指向的对象不一样,所以在使用时需要特别注意。下面使用一个具体示例来演示 this 的应用。
【例 2】this 的应用。
!doctype html html head meta charset= utf-8 title this的应用 /title style li{width:100px;height:150px;float:left;margin-right:30px;list-style:none; background:#f1f1f1;position:relative;} div{width:80px;height:120px;background:red;position:absolute;top:100px; left:10px;display:none;} /style script window.onload = function (){ var aLi = document.getElementsByTagName( li //通过标签名获取所有li元素 for(var i = 0; i aLi.length; i++){ //光标移到某个li元素上时显示div元素 aLi[i].onmouseover = function (){ //使用this指代当前元素,即光标移到的那个li元素 //获取当前li元素的第一个子元素div,并设置它的显示样式为block,即显示div this.getElementsByTagName( div )[0].style.display= block //光标移开某个li元素上时隐藏div元素 aLi[i].onmouseout = function (){ //获取当前li元素的第一个子元素div,并设置它的显示样式为none,即隐藏div this.getElementsByTagName( div )[0].style.display= none /script /head body div /div /li div /div /li div /div /li /ul /body /html
例 2 实现的功能是:页面中存在 3 个 li 元素,当光标移到任何一个 li 元素上时,会在其下面显示一个 div,一旦光标移开 li 元素,显示的 div 又会隐藏。在上述代码中,我们看到 div 的显示和隐藏都是通过事件调用匿名函数来实现的,所以在匿名函数中的 this 指向触发事件的那个 li 元素,因而可以通过它来获取 li 的子元素 div。
对上述 JS 代码作如下修改:
script window.onload = function (){ var aLi = document.getElementsByTagName( li for(var i = 0; i aLi.length; i++){ aLi[i].onmouseover = function (){ show(); aLi[i].onmouseout = function (){ hide(); function show(){ this.getElementsByTagName( div )[0].style.display= block function hide(){ this.getElementsByTagName( div )[0].style.display= none /script
此时,对 li 元素来说,show() 和 hide() 并不是它的当前函数,因为它们的调用并不是直接由 li 元素来完成的,而是由 window 对象来完成,所以在这两个函数体中的 this 指向的是 window 对象,而不是 li 对象。这样使用上面的代码就无法实现例 2 的功能。要让上述代码实现例 2 的功能,需要将 show() 和 hide() 中的 this 指向 li 元素,如果直接用 this,是无法实现这个需求的。
此时这里需要变通一下,不直接使用 this,而是用一个变量,但这个变量必须事先在 li 元素的光标移入和移出事件调用的匿名函数中赋值,且值等于 this,这样,在 show() 和 hide() 中使用这个变量就等效于使用触发光标事件的那个 li 元素。下面按照这个思路修改上述代码:
script window.onload = function (){ var aLi = document.getElementsByTagName( li var that = null; for(var i = 0; i aLi.length; i++){ aLi[i].onmouseover = function (){ that = this; show(); aLi[i].onmouseout = function (){ that = this; hide(); function show(){ that.getElementsByTagName( div )[0].style.display= block function hide(){ that.getElementsByTagName( div )[0].style.display= none /script
上述代码中变通使用 this 的方法是一种比较常用的方法,在后面的定时器中会再次使用这种方法。
23990.html
htmljavaJavaScript相关文章
- js数组遍历的方法_图的遍历及应用实验总结
- js 手动触发input事件
- 使用 Dapr JS SDK 让 Nest.js 集成 Dapr(微软开源的分布式应用程序运行时)
- Node.js 应用高 CPU 占用率的分析方法
- 使用 Dynatrace 对 Node.js 应用的性能数据进行分析
- Node.js 应用访问 https 服务器时遇到的错误消息 unable to get local issuer certificate
- JS面试题-js新增基本数据类型BigInt
- JS面试、技巧总结点一-变量提升/函数提升
- JS+CSS自定义右键菜单美化
- 双向链表[js实现] 【4】
- 【JS 逆向百例】猿人学系列 web 比赛第五题:js 混淆 - 乱码增强,详细剖析
- ab77b6ea7f3fbf79.JS代码报错什么原因?
- clipboard.js:最轻便的复制页面内容到剪切板的JS
- JS 中屏幕、浏览器和文档的高度、宽度和距离详解编程语言
- JS技术连接Oracle数据库实现数据交互(js连接oracle实例)
- 使用JS在网页中连接Oracle数据库(js网页链接oracle)
- 使用JS控制Oracle数据库的更新(js控制oracle更新)
- 从前端JS里请求Redis资源,搭建高性能应用(前端js请求redis)
- Oracle中JS的优势让数据库性能提升(oracle中 js)
- 使用Oracle和JS开发新一代应用仿真世界(oracle js)
- php和js交互一例-PHP教程,PHP应用
- 延时重复执行函数lLoopRun.js
- js手机号码合法性验证代码集合
- Js回车换行处理的办法及replace方法应用
- js中parseFloat(参数1,参数2)定义和用法及注意事项
- js得到文件后缀(通过正则实现)
- php与js的区别是什么
- js综合应用实例简单的表格统计
- 利用毫秒减值计算时长的js代码
- JS.elementGetStyle(element,style)应用示例
- js判断ie版本号的简单实现代码
- JS获取客户端IP地址、MAC和主机名的7个方法汇总