再次谈论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 相关文章推荐
10个基于Jquery的幻灯片插件教程
Oct 29 Javascript
JavaScript中的Array对象使用说明
Jan 17 Javascript
textarea中的手动换行处理的jquery代码
Feb 26 Javascript
Javascript实现商品秒杀倒计时(时间与服务器时间同步)
Sep 16 Javascript
JavaScript黑洞数字之运算路线查找算法(递归算法)实例
Jan 28 Javascript
一个仿微博登陆邮箱提示框js开发案例
Jul 28 Javascript
纯JavaScript手写图片轮播代码
Oct 20 Javascript
Javascript快速实现浏览器系统通知
Aug 26 Javascript
解决vue的过渡动画无法正常实现问题
Oct 31 Javascript
微信小程序wx.request的简单封装
Nov 13 Javascript
node.JS路径解析之PATH模块使用方法详解
Feb 06 Javascript
详解react组件通讯方式(多种)
May 06 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判断远程url是否有效的几种方法小结
2011/10/08 PHP
php基于GD库画五星红旗的方法
2015/02/24 PHP
php将字符串随机分割成不同长度数组的方法
2015/06/01 PHP
PHP中遍历数组的三种常用方法实例分析
2019/06/24 PHP
漂亮的widgets,支持换肤和后期开发新皮肤
2007/04/23 Javascript
jQuery EasyUI API 中文文档 - Pagination分页
2011/09/29 Javascript
详解JavaScript时间格式化
2015/12/23 Javascript
Angularjs 创建可复用组件实例代码
2016/10/09 Javascript
angular源码学习第一篇 setupModuleLoader方法
2016/10/20 Javascript
JS判断是否为JSON对象及是否存在某字段的方法(推荐)
2016/11/29 Javascript
JavaScript中捕获/阻止捕获、冒泡/阻止冒泡方法
2016/12/07 Javascript
nodeJS删除文件方法示例
2016/12/25 NodeJs
js阻止移动端页面滚动的两种方法
2017/01/25 Javascript
JS简单实现数组去重的方法示例
2017/03/27 Javascript
基于Cookie常用操作以及属性介绍
2017/09/07 Javascript
nodejs判断文件、文件夹是否存在及删除的方法
2017/11/10 NodeJs
vue路由事件beforeRouteLeave及组件内定时器的清除方法
2018/09/29 Javascript
浅谈redux, koa, express 中间件实现对比解析
2019/05/23 Javascript
JavaScript定时器常见用法实例分析
2019/11/15 Javascript
JS实现多功能计算器
2020/10/28 Javascript
[00:32]10月24、25日 辉夜杯外卡赛附加赛开赛!
2015/10/23 DOTA
Python编程中的反模式实例分析
2014/12/08 Python
Python使用回溯法子集树模板解决爬楼梯问题示例
2017/09/08 Python
Python 逐行分割大txt文件的方法
2017/10/10 Python
Java及python正则表达式详解
2017/12/27 Python
pycharm运行程序时在Python console窗口中运行的方法
2018/12/03 Python
Python获取航线信息并且制作成图的讲解
2019/01/03 Python
python3.6编写的单元测试示例
2019/08/17 Python
python 用户交互输入input的4种用法详解
2019/09/24 Python
django rest framework使用django-filter用法
2020/07/15 Python
Django CBV模型源码运行流程详解
2020/08/17 Python
夏尔巴人登珠峰品牌:Sherpa Adventure Gear
2018/02/08 全球购物
项目采购员岗位职责
2014/04/15 职场文书
教师自我剖析材料(四风问题)
2014/09/30 职场文书
2015年医务科工作总结范文
2015/05/26 职场文书
教育教学读书笔记
2015/07/02 职场文书