再次谈论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字符串的各种格式的转换 ToString,Format
Aug 08 Javascript
JavaScript中的作用域链和闭包
Jun 30 Javascript
jquery实现图片随机排列的方法
May 04 Javascript
JavaScript鼠标特效大全
Sep 13 Javascript
自学实现angularjs依赖注入
Dec 20 Javascript
解决IE7中使用jQuery动态操作name问题
Aug 28 jQuery
vue在使用ECharts时的异步更新和数据加载详解
Nov 22 Javascript
VS Code转换大小写、修改选中文字或代码颜色的方法
Dec 15 Javascript
如何解决React官方脚手架不支持Less的问题(小结)
Sep 12 Javascript
Vue递归组件+Vuex开发树形组件Tree--递归组件的简单实现
Apr 01 Javascript
JS实现的进制转换,浮点数相加,数字判断操作示例
Nov 09 Javascript
JS数组方法join()用法实例分析
Jan 18 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+AJAX实现投票功能的方法
2015/09/28 PHP
PHP使用strtotime获取上个月、下个月、本月的日期
2015/12/30 PHP
php图片裁剪函数
2018/10/31 PHP
Laravel6.2中用于用户登录的新密码确认流程详解
2019/10/16 PHP
10条建议帮助你创建更好的jQuery插件
2015/05/18 Javascript
jQuery实现向下滑出的二级菜单效果实例
2015/08/22 Javascript
基于JavaScript如何实现私有成员的语法特征及私有成员的实现方式
2015/10/28 Javascript
干货分享:让你分分钟学会javascript闭包
2015/12/25 Javascript
jQuery序列化表单成对象的简单实现
2016/11/29 Javascript
Bootstrap CSS布局之按钮
2016/12/17 Javascript
js原生Ajax的封装和原理详解
2017/03/11 Javascript
IScroll那些事_当内容不足时下拉刷新的解决方法
2017/07/18 Javascript
判断jQuery是否加载完成,没完成继续判断的解决方法
2017/12/06 jQuery
vue2.0项目实现路由跳转的方法详解
2018/06/21 Javascript
JavaScript实现浅拷贝与深拷贝的方法分析
2018/07/05 Javascript
JavaScript面向对象程序设计中对象的定义和继承详解
2019/07/29 Javascript
Typescript的三种运行方式(小结)
2019/09/18 Javascript
微信头像地址失效踩坑记附带解决方案
2019/09/23 Javascript
Vue快速实现通用表单验证的示例代码
2020/01/09 Javascript
JS实现点星星消除小游戏
2020/03/24 Javascript
Javascript生成器(Generator)的介绍与使用
2021/01/31 Javascript
python处理PHP数组文本文件实例
2014/09/18 Python
解析Python编程中的包结构
2015/10/25 Python
python实现微信每日一句自动发送给喜欢的人
2019/04/29 Python
python反编译学习之字节码详解
2019/05/19 Python
python实现ip地址查询经纬度定位详解
2019/08/30 Python
基于python实现FTP文件上传与下载操作(ftp&amp;sftp协议)
2020/04/01 Python
美国汽配连锁巨头Pep Boys官网:轮胎更换、汽车维修服务和汽车零部件
2017/01/14 全球购物
美国眼镜在线零售商:Dualens
2019/12/07 全球购物
市场部专员岗位职责
2013/11/30 职场文书
教育专业个人求职信
2013/12/02 职场文书
城建学院毕业生自荐信
2014/01/31 职场文书
物业总经理助理岗位职责
2014/06/29 职场文书
煤矿百日安全活动总结
2015/05/07 职场文书
Redis实战高并发之扣减库存项目
2022/04/14 Redis
bose降噪耳机音能消除人声吗
2022/04/19 数码科技