再次谈论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 25 Javascript
jQuery的实现原理的模拟代码 -2 数据部分
Aug 01 Javascript
setTimeout自动触发一个js的方法
Jan 15 Javascript
window resize和scroll事件的基本优化思路
Apr 29 Javascript
js获取对象、数组的实际长度,元素实际个数的实现代码
Jun 08 Javascript
轻松掌握JavaScript策略模式
Aug 25 Javascript
JS解析url查询参数的简单代码
Aug 06 Javascript
vue组件传递对象中实现单向绑定的示例
Feb 28 Javascript
JS中原始值和引用值的储存方式示例详解
Mar 23 Javascript
es6中比较有用的7个技巧小结
Jul 12 Javascript
原生js实现简单轮播图
Oct 26 Javascript
解决vue项目中出现Invalid Host header的问题
Nov 17 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
Drupal7中常用的数据库操作实例
2014/03/02 PHP
PHP提交表单失败后如何保留已经填写的信息
2014/06/20 PHP
Google Suggest ;-) 基于js的动态下拉菜单
2006/10/11 Javascript
有道JavaScript监听浏览器的问题
2010/06/23 Javascript
js限制textarea每行输入字符串长度的代码
2012/10/31 Javascript
jquery比较简洁的软键盘特效实现方法
2015/03/19 Javascript
javascript实现网页子页面遍历回调的方法(涉及 window.frames、递归函数、函数上下文)
2015/07/27 Javascript
javascript瀑布流布局实现方法详解
2016/02/17 Javascript
jQuery动态添加可拖动元素完整实例(附demo源码下载)
2016/06/21 Javascript
Angular2表单自定义验证器的实现
2016/10/19 Javascript
给easyui的datebox控件添加清空按钮的实现方法
2016/11/09 Javascript
Vue2.0实现购物车功能
2017/06/05 Javascript
JS使用正则表达式验证身份证号码
2017/06/23 Javascript
手把手教你 CKEDITOR 4 扩展插件制作
2019/06/18 Javascript
layer.open弹层查看缩略图的原图,自适应大小的实例
2019/09/05 Javascript
浅谈vuex为什么不建议在action中修改state
2020/02/02 Javascript
浅谈vue使用axios的回调函数中this不指向vue实例,为undefined
2020/09/21 Javascript
Django查找网站项目根目录和对正则表达式的支持
2015/07/15 Python
详解python中的文件与目录操作
2017/07/11 Python
mysql 之通过配置文件链接数据库
2017/08/12 Python
python多线程socket编程之多客户端接入
2017/09/12 Python
Python3爬取英雄联盟英雄皮肤大图实例代码
2018/11/14 Python
解决PyCharm不运行脚本,而是运行单元测试的问题
2019/01/17 Python
Python使用线程来接收串口数据的示例
2019/07/02 Python
Python列表删除元素del、pop()和remove()的区别小结
2019/09/11 Python
django框架ModelForm组件用法详解
2019/12/11 Python
django 文件上传功能的相关实例代码(简单易懂)
2020/01/22 Python
python实现简单遗传算法
2020/09/18 Python
爱普生美国官网:Epson美国
2018/11/05 全球购物
Linux如何压缩可执行文件
2013/10/21 面试题
放飞中国梦演讲稿
2014/04/23 职场文书
注册资产评估专业求职信
2014/07/16 职场文书
邀请函样本
2015/02/02 职场文书
幼儿教师远程研修感悟
2015/11/18 职场文书
小学班长竞选稿
2015/11/20 职场文书
css实现两栏布局,左侧固定宽,右侧自适应的多种方法
2021/08/07 HTML / CSS