再次谈论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 相关文章推荐
JS学习之一个简易的日历控件
Mar 24 Javascript
jQuery实现可收缩展开的级联菜单实例代码
Nov 27 Javascript
js判断字符长度以及中英文数字等
Dec 31 Javascript
js中运算符&amp;&amp; 和 || 的使用记录
Aug 21 Javascript
判断window.onload是否多次使用的方法
Sep 21 Javascript
jQuery树形插件jquery.simpleTree.js用法分析
Sep 05 Javascript
vue2.0 elementUI制作面包屑导航栏
Feb 22 Javascript
利用vue和element-ui设置表格内容分页的实例
Mar 02 Javascript
详解原生JS动态添加和删除类
Mar 26 Javascript
Vue.js + Nuxt.js 项目中使用 Vee-validate 表单校验
Apr 22 Javascript
layui 数据表格 根据值(1=业务,2=机构)显示中文名称示例
Oct 26 Javascript
vscode自定义vue模板的实现
Jan 27 Vue.js
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
重置版宣传动画
2020/04/09 魔兽争霸
PHP 中的一些经验积累
2006/10/09 PHP
特转载一高手总结PHP学习资源和链接.
2006/12/05 PHP
利用PHP制作简单的内容采集器的原理分析
2008/10/01 PHP
php设计模式 Command(命令模式)
2011/06/26 PHP
PHP IE中下载附件问题解决方法
2014/01/07 PHP
Js四则运算函数代码
2012/07/21 Javascript
HTML复选框和单选框 checkbox和radio事件介绍
2012/12/12 Javascript
让js弹出窗口居前显示的实现方法
2013/07/10 Javascript
JavaScript中的连字符详解
2013/11/28 Javascript
Node.js刷新session过期时间的实现方法推荐
2016/05/18 Javascript
轻松掌握JavaScript中的Math object数学对象
2016/05/26 Javascript
AngularJS实践之使用NgModelController进行数据绑定
2016/10/08 Javascript
JS树形菜单组件Bootstrap TreeView使用方法详解
2016/12/21 Javascript
jQuery 表单序列化实例代码
2017/06/11 jQuery
Angular通过angular-cli来搭建web前端项目的方法
2017/07/27 Javascript
详解动画插件wow.js的使用方法
2017/09/13 Javascript
基于JavaScript实现简单的音频播放功能
2018/01/07 Javascript
小程序指纹验证的实现代码
2018/12/04 Javascript
vue实现抖音时间转盘
2019/09/08 Javascript
js实现幻灯片轮播图
2020/08/14 Javascript
Python的Flask框架及Nginx实现静态文件访问限制功能
2016/06/27 Python
python 找出list中最大或者最小几个数的索引方法
2018/10/30 Python
python字符串替换re.sub()方法解析
2019/09/18 Python
Python中断多重循环的思路总结
2019/10/04 Python
python定时任务 sched模块用法实例
2019/11/04 Python
CSS3 text-shadow实现文字阴影效果
2016/02/24 HTML / CSS
美国潜水装备、水肺潜水和浮潜设备商店:Leisure Pro
2018/08/08 全球购物
MVC的各个部分都有那些技术来实现?如何实现?
2016/04/21 面试题
客服部工作职责范本
2014/02/14 职场文书
教师师德考核自我评价
2014/09/13 职场文书
2015年精神文明建设工作总结
2015/04/21 职场文书
2015年世界无烟日活动方案
2015/05/04 职场文书
golang 在windows中设置环境变量的操作
2021/04/29 Golang
如何使用PyCharm及常用配置详解
2021/06/03 Python
Java Redisson多策略注解限流
2022/09/23 Java/Android