再次谈论Javascript中的this


Posted in Javascript onJune 23, 2016

 一直对Javascript中的this都有一种似是而非的感觉,今天突然感觉豁然开朗,特此记录一下。

咱们先看个栗子:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>this的使用</title>
<script type="text/javascript">
var Car,tesla;
Car=function () {
this.start=function(){
console.log('car started');
};
this.turnKye=function () {
var carKey=document.getElementById('car_key');
carKey.onclick=function () {
this.start(); 
};
}
return this;
}
tesla=new Car();
tesla.turnKye();
</script>
</head>
<body>
<input type="button" id="car_key" value="test" />
</body>
</html>

咋一看这段代码没有什么问题,但是由于对于this的错误理解最终导致错误的结果。我们在元素car_key上面绑定了click事件,认为在car的类中嵌套绑定click事件就可以让这个dom元素访问car的this上下文。这种方式看起来很合理,但是不幸的是它并不工作。

在Javascript中,this关键字总是指向正执行的作用域的所有者。

请大家仔细揣摩上面那句话。正如我们所知,函数调用会产生新的作用域,一点onclick事件被触发,this就指向了dom元素而不是Car的类。

那我们怎么做才会让它能正常工作呢?我们通常会把this赋值给一个局部的自由变量(比如that,_this,self,me等,这个在许多的框架里面都有体现)来避开作用域带来的问题。这里使用局部变量来重写之前的方法:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>this的使用</title>
</head>
<body>
<input type="button" id="car_key" value="test" />
<script type="text/javascript">
var Car,tesla;
Car=function () {
this.start=function(){
console.log('car started');
};
this.turnKye=function () {
var that=this;
var carKey=document.getElementById('car_key');
carKey.onclick=function () {
that.start(); 
};
}
return this;
}
tesla=new Car();
tesla.turnKye();
</script>
</body>
</html>

由于that是一个自由变量,onclick事件的出发并不会引起它的重新定义。

  如果你熟悉ES6的话可以使用胖箭头符号,这更简洁和更容易理解,如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>this的使用</title>
</head>
<body>
<input type="button" id="car_key" value="test" />
<script type="text/javascript">
var Car,tesla;
Car=function () {
this.start=function(){
console.log('car started');
};
this.turnKye=function () {
//var that=this;
var carKey=document.getElementById('car_key');
//carKey.onclick=function () {
// that.start(); 
//};
carKey.onclick=()=>this.start();
}
return this;
}
tesla=new Car();
tesla.turnKye();
</script>
</body>
</html>

当然我们也可以使用绑定函数的方法来解决这个问题:如下

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>this的使用</title>
</head>
<body>
<input type="button" id="car_key" value="test" />
<script type="text/javascript">
var Car,tesla;
Car=function () {
this.start=function(){
console.log('car started');
};
var click=function(){
this.start(); 
}
this.turnKye=function () {
//var that=this;
var carKey=document.getElementById('car_key');
carKey.onclick=click.bind(this);
}
return this;
}
tesla=new Car();
tesla.turnKye();
</script>
</body>
</html>

其实这些在学习React的时候,绑定事件的时候遇到的坑,那时候只知道这么写,不知道怎么回事,今天突然感觉豁然开朗。希望对大家有所帮助。

Javascript 相关文章推荐
IE与FF下javascript获取网页及窗口大小的区别详解
Jan 14 Javascript
JavaScript实现动态创建CSS样式规则方案
Sep 06 Javascript
基于jquery实现简单的手风琴特效
Nov 24 Javascript
基于jquery实现ajax无刷新评论
Aug 19 Javascript
jQueryUI中的datepicker使用方法详解
May 25 Javascript
详解vue-validator(vue验证器)
Jan 16 Javascript
原生JS 购物车及购物页面的cookie使用方法
Aug 21 Javascript
使用百度地图实现地图网格的示例
Feb 06 Javascript
JavaScript面向对象程序设计中对象的定义和继承详解
Jul 29 Javascript
LayUI动态设置checkbox不显示的解决方法
Sep 02 Javascript
解决vuex数据异步造成初始化的时候没值报错问题
Nov 13 Javascript
ant design vue中表格指定格式渲染方式
Oct 28 Javascript
BootStrap使用popover插件实现鼠标经过显示并保持显示框
Jun 23 #Javascript
Bootstrap导航条可点击和鼠标悬停显示下拉菜单的实现代码
Jun 23 #Javascript
Bootstrap弹出带合法性检查的登录框实例代码【推荐】
Jun 23 #Javascript
JS留言功能的简单实现案例(推荐)
Jun 23 #Javascript
Bootstrap实现登录校验表单(带验证码)
Jun 23 #Javascript
JavaScript自学笔记(必看篇)
Jun 23 #Javascript
Bootstrap中文本框的宽度变窄并且加入一副验证码图片的实现方法
Jun 23 #Javascript
You might like
打造计数器DIY三步曲(上)
2006/10/09 PHP
PHP递归实现快速排序的方法示例
2017/12/18 PHP
Yii 框架入口脚本示例分析
2020/05/19 PHP
jquery.cvtooltip.js 基于jquery的气泡提示插件
2010/11/19 Javascript
javascript控制swfObject应用介绍
2012/11/29 Javascript
鼠标滚轮控制网页横向移动实现思路
2013/03/22 Javascript
你必须知道的Javascript知识点之&quot;深入理解作用域链&quot;的介绍
2013/04/23 Javascript
ECMAScript 6即将带给我们新的数组操作方法前瞻
2015/01/06 Javascript
微信小程序 video组件详解
2016/10/25 Javascript
node+express制作爬虫教程
2016/11/11 Javascript
微信小程序购物商城系统开发系列-目录结构介绍
2016/11/21 Javascript
js倒计时显示实例
2016/12/11 Javascript
Angular.js项目中使用gulp实现自动化构建以及压缩打包详解
2017/07/19 Javascript
vue2.0实现音乐/视频播放进度条组件
2018/06/06 Javascript
jQuery实现鼠标移入移出事件切换功能示例
2018/09/06 jQuery
bootstrap table.js动态填充单元格数据的多种方法
2019/07/18 Javascript
node实现爬虫的几种简易方式
2019/08/22 Javascript
antd-mobile ListView长列表的数据更新遇到的坑
2020/04/08 Javascript
vue data变量相互赋值后被实时同步的解决步骤
2020/08/05 Javascript
Python编写合并字典并实现敏感目录的小脚本
2019/02/26 Python
详解Python中的正斜杠与反斜杠
2019/08/09 Python
Python箱型图绘制与特征值获取过程解析
2019/10/22 Python
在 Jupyter 中重新导入特定的 Python 文件(场景分析)
2019/10/27 Python
python3常用的数据清洗方法(小结)
2019/10/31 Python
结束运行python的方法
2020/06/16 Python
python导入库的具体方法
2020/06/18 Python
金宝贝童装官网:Gymboree
2016/08/31 全球购物
Expedia加拿大官方网站:加拿大最大的在线旅游提供商
2017/12/31 全球购物
Java中compareTo和compare的区别
2016/04/12 面试题
团员学习总结的自我评价范文
2013/10/14 职场文书
计算机学生求职信范文
2014/01/30 职场文书
《九色鹿》教学反思
2014/02/27 职场文书
安全施工标语
2014/06/07 职场文书
办公室禁烟通知
2015/04/23 职场文书
企业反腐倡廉心得体会
2015/08/15 职场文书
会议承办单位欢迎词
2019/07/09 职场文书