再次谈论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 动态文字滚动的例子
Jan 17 Javascript
Javascript浅谈之引用类型
Dec 18 Javascript
JQuery调用绑定click事件的3种写法
Mar 28 Javascript
jquery插件bxslider用法实例分析
Apr 16 Javascript
jQuery提示插件alertify使用指南
Apr 21 Javascript
TypeScript 学习笔记之基本类型
Jun 19 Javascript
JavaScript的for循环中嵌套一个点击事件的问题解决
Mar 03 Javascript
JavaScript使用math.js进行精确计算操作示例
Jun 19 Javascript
vue生成token并保存到本地存储中
Jul 17 Javascript
ES6入门教程之变量的解构赋值详解
Apr 13 Javascript
解决$store.getters调用不执行的问题
Nov 08 Javascript
angula中使用iframe点击后不执行变更检测的问题
May 10 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
php中截取字符串支持utf-8
2007/01/18 PHP
php获取通过http协议post提交过来xml数据及解析xml
2012/12/16 PHP
php操作XML、读取数据和写入数据的实现代码
2014/08/15 PHP
thinkphp备份数据库的方法分享
2015/01/04 PHP
提高Laravel应用性能方法详解
2019/06/24 PHP
php求斐波那契数的两种实现方式【递归与递推】
2019/09/09 PHP
让getElementsByName适应IE和firefox的方法
2007/09/24 Javascript
一款Jquery 分页插件的改造方法(服务器端分页)
2011/07/11 Javascript
js跨域问题浅析及解决方法优缺点对比
2014/11/08 Javascript
如何使用jquery修改css中带有!important的样式属性
2016/04/28 Javascript
跨域请求的完美解决方法(JSONP, CORS)
2016/06/12 Javascript
Ionic2系列之使用DeepLinker实现指定页面URL
2016/11/21 Javascript
js实现贪吃蛇小游戏(容易理解)
2017/01/22 Javascript
Bootstrap风格的zTree右键菜单
2017/02/17 Javascript
js实现网页定位导航功能
2017/03/07 Javascript
浅谈vue项目重构技术要点和总结
2018/01/23 Javascript
微信小程序实现列表下拉刷新上拉加载
2020/07/29 Javascript
详解如何在webpack中做预渲染降低首屏空白时间
2018/08/22 Javascript
微信小程序上传文件到阿里OSS教程
2019/05/20 Javascript
微信分享invalid signature签名错误踩过的坑
2020/04/11 Javascript
将Vue组件库更换为按需加载的方法步骤
2020/05/06 Javascript
Python脚本实现12306火车票查询系统
2016/09/30 Python
Python数据抓取爬虫代理防封IP方法
2018/12/23 Python
python中正则表达式与模式匹配
2019/05/07 Python
python实现程序重启和系统重启方式
2020/04/16 Python
python 获取计算机的网卡信息
2021/02/18 Python
丝芙兰法国官网:SEPHORA法国
2016/09/01 全球购物
企业授权委托书范本
2014/04/02 职场文书
个人承诺书怎么写
2014/05/24 职场文书
园林专业毕业生自荐信
2014/07/04 职场文书
车贷收入证明范本
2014/09/14 职场文书
学校教学工作总结2015
2015/05/19 职场文书
Python还能这么玩之只用30行代码从excel提取个人值班表
2021/06/05 Python
小喇叭开始广播了! 四十多年前珍贵老照片
2022/05/09 无线电
Python使用pyecharts控件绘制图表
2022/06/05 Python
Android开发手册Chip监听及ChipGroup监听
2022/06/10 Java/Android