再次谈论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 相关文章推荐
FLASH 广告之外的链接
Dec 16 Javascript
两个Javascript小tip资料
Nov 23 Javascript
JS父页面与子页面相互传值方法
Mar 05 Javascript
使用JavaScript实现连续滚动字幕效果的方法
Jul 07 Javascript
简单讲解AngularJS的Routing路由的定义与使用
Mar 05 Javascript
轻松掌握JavaScript中介者模式
Aug 26 Javascript
BootStrap按钮标签及基本样式
Nov 23 Javascript
ES6字符串模板,剩余参数,默认参数功能与用法示例
Apr 06 Javascript
React之PureComponent的使用作用
Jul 10 Javascript
iview在vue-cli3如何按需加载的方法
Oct 31 Javascript
Vue实现仿iPhone悬浮球的示例代码
Mar 13 Javascript
React自定义hook的方法
Jun 25 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代码
2011/11/27 PHP
关于PHP内存溢出问题的解决方法
2013/06/25 PHP
PHP生成图片验证码功能示例
2017/01/12 PHP
PHP 结合 Boostrap 结合 js 实现学生列表删除编辑及搜索功能
2019/05/21 PHP
Laravel 模型关联基础教程详解
2019/09/17 PHP
php连接sftp的作用以及实例代码
2019/09/23 PHP
学习ExtJS table布局
2009/10/08 Javascript
13个绚丽的Jquery 界面设计网站推荐
2010/09/28 Javascript
JavaScript中instanceof与typeof运算符的用法及区别详细解析
2013/11/19 Javascript
详解JS面向对象编程
2016/01/24 Javascript
JS 滚动事件window.onscroll与position:fixed写兼容IE6的回到顶部组件
2016/10/10 Javascript
使用base64对图片的二进制进行编码并用ajax进行显示
2017/01/03 Javascript
javascript 使用正则test( )第一次是 true,第二次是false
2017/02/22 Javascript
微信小程序 sha1 实现密码加密实例详解
2017/07/06 Javascript
Vue学习笔记进阶篇之过渡状态详解
2017/07/14 Javascript
JavaScript Drum Kit 指南(纯 JS 模拟敲鼓效果)
2017/07/23 Javascript
Python 连连看连接算法
2008/11/22 Python
初学Python函数的笔记整理
2015/04/07 Python
在Python中用split()方法分割字符串的使用介绍
2015/05/20 Python
Python字符编码判断方法分析
2016/07/01 Python
使用Python制作微信跳一跳辅助
2018/01/31 Python
Python cookbook(数据结构与算法)将名称映射到序列元素中的方法
2018/03/22 Python
python http基本验证方法
2018/12/26 Python
Python3.6中Twisted模块安装的问题与解决
2019/04/15 Python
使用Python操作ArangoDB的方法步骤
2020/02/02 Python
Python内建序列通用操作6种实现方法
2020/03/26 Python
基于HTML5代码实现折叠菜单附源码下载
2015/11/27 HTML / CSS
会计大学生职业生涯规划书范文
2014/01/13 职场文书
小学毕业感言500字
2014/02/28 职场文书
社区维稳工作方案
2014/06/06 职场文书
群众路线教育实践活动自我剖析思想汇报
2014/10/04 职场文书
2015年档案管理员工作总结
2015/05/13 职场文书
演讲开场白台词大全
2015/05/29 职场文书
2016年世界人口日宣传活动总结
2016/04/05 职场文书
创业计划书之酒吧
2019/12/02 职场文书
CSS 一行代码实现头像与国旗的融合
2021/10/24 HTML / CSS