再次谈论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 相关文章推荐
浅谈JavaScript中面向对象技术的模拟
Sep 25 Javascript
css图片自适应大小
Nov 28 Javascript
js 通用javascript函数库整理
Aug 14 Javascript
jQuery点击自身以外地方关闭弹出层的简单实例
Dec 24 Javascript
JavaScript获得url所有参数键值表的方法
Mar 21 Javascript
JavaScript DOM操作表格及样式
Apr 13 Javascript
JS图片等比例缩放方法完整示例
Aug 03 Javascript
JavaScript html5利用FileReader实现上传功能
Mar 27 Javascript
vue 如何添加全局函数或全局变量以及单页面的title设置总结
Jun 01 Javascript
vue2.0移除或更改的一些东西(移除index key)
Aug 28 Javascript
基于vue的验证码组件的示例代码
Jan 22 Javascript
vue中解决chrome浏览器自动播放音频和MP3语音打包到线上的实现方法
Oct 09 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
信用卡效验程序
2006/10/09 PHP
php 生成唯一id的几种解决方法
2013/03/08 PHP
PHP中的按位与和按位或操作示例
2014/01/27 PHP
如何使用GDB调试PHP程序
2015/12/08 PHP
从性能方面考虑PHP下载远程文件的3种方法
2015/12/29 PHP
详解thinkphp实现excel数据的导入导出(附完整案例)
2016/12/29 PHP
输入框的字数时时统计—关于 onpropertychange 和 oninput 使用
2011/10/21 Javascript
用C/C++来实现 Node.js 的模块(一)
2014/09/24 Javascript
Javascript函数式编程语言
2015/10/11 Javascript
原生js制作日历控件实例分享
2016/04/06 Javascript
BootStrap实现带有增删改查功能的表格(DEMO详解)
2016/10/26 Javascript
vue2.0页面前进刷新回退不刷新的实现方法
2018/07/31 Javascript
Vue实现远程获取路由与页面刷新导致404错误的解决
2019/01/31 Javascript
回顾Javascript React基础
2019/06/15 Javascript
在vue中使用vant TreeSelect分类选择组件操作
2020/11/02 Javascript
vue项目中使用rem,在入口文件添加内容操作
2020/11/11 Javascript
利用Python绘制数据的瀑布图的教程
2015/04/07 Python
Python中使用pprint函数进行格式化输出的教程
2015/04/07 Python
粗略分析Python中的内存泄漏
2015/04/23 Python
Python实现打印螺旋矩阵功能的方法
2017/11/21 Python
python+django加载静态网页模板解析
2017/12/12 Python
新手如何发布Python项目开源包过程详解
2019/07/11 Python
PyQt5 closeEvent关闭事件退出提示框原理解析
2020/01/08 Python
详解Python 中的 defaultdict 数据类型
2021/02/22 Python
纽约著名的服装辅料来源:M&J Trimming
2017/07/26 全球购物
亚马逊海外购:亚马逊美国、英国、日本、德国直邮
2021/03/18 全球购物
车辆维修工自我评价怎么写
2013/09/20 职场文书
教学大赛获奖感言
2014/01/15 职场文书
自动化专业职业生涯规划书范文
2014/01/16 职场文书
骨干教师培训感言
2014/01/16 职场文书
工商治理实习生的自我评价分享
2014/02/20 职场文书
学校评语大全
2014/05/06 职场文书
中学生的1000字检讨书
2014/10/11 职场文书
家属答谢词
2015/01/05 职场文书
被告代理词范文
2015/05/25 职场文书
vue实现无缝轮播效果(跑马灯)
2021/05/14 Vue.js