再次谈论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 相关文章推荐
30分钟就入门的正则表达式基础教程
Feb 25 Javascript
Javascript 遮罩层和加载效果代码
Aug 01 Javascript
JS幻灯片可循环播放可平滑旋转带滚动导航(自写)
Aug 05 Javascript
JavaScript 命名空间 使用介绍
Aug 29 Javascript
查看大图功能代码jquery版
Nov 05 Javascript
超简单JS二级、多级联动的简单实例
Feb 18 Javascript
js数组依据下标删除元素
Apr 14 Javascript
jquery实现select下拉框美化特效代码分享
Aug 18 Javascript
微信小程序 选择器(时间,日期,地区)实例详解
Nov 16 Javascript
bootstrap可编辑下拉框jquery.editable-select
Oct 12 jQuery
vue组件实现可搜索下拉框扩展
Oct 23 Javascript
angularJs在多个控制器中共享服务数据的方法
Sep 30 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字符串长度计算 - strlen()函数使用介绍
2013/10/15 PHP
php 后端实现JWT认证方法示例
2018/09/04 PHP
PHP自动生成缩略图函数的源码示例
2019/03/18 PHP
JS获取节点的兄弟,父级,子级元素的方法
2014/01/09 Javascript
js判断元素是否隐藏的方法
2014/06/09 Javascript
JavaScript生成SQL查询表单的方法
2015/08/13 Javascript
Knockout自定义绑定创建方法
2015/12/26 Javascript
Vuejs实现带样式的单文件组件新方法
2017/05/02 Javascript
基于AngularJS实现表单验证功能
2017/07/28 Javascript
Vue.JS项目中5个经典Vuex插件
2017/11/28 Javascript
从零开始搭建webpack+react开发环境的详细步骤
2018/05/18 Javascript
详解使用vue-admin-template的优化历程
2018/05/20 Javascript
微信小程序中遇到的iOS兼容性问题小结
2018/11/14 Javascript
js中int和string数据类型互相转化实例
2019/01/16 Javascript
浅谈Vue3.0新版API之composition-api入坑指南
2020/04/30 Javascript
Vue实现点击当前行变色
2020/12/14 Vue.js
vue自定义组件实现双向绑定
2021/01/13 Vue.js
JS相册图片抖动放大展示效果的示例代码
2021/01/29 Javascript
浅谈Python程序与C++程序的联合使用
2015/04/07 Python
Python语法分析之字符串格式化
2019/06/13 Python
pandas 中对特征进行硬编码和onehot编码的实现
2019/12/20 Python
python使用Geany编辑器配置方法
2020/02/21 Python
pyinstaller打包找不到文件的问题解决
2020/04/15 Python
在Keras中利用np.random.shuffle()打乱数据集实例
2020/06/15 Python
加拿大领先的时尚和体育零售商:Sporting Life
2019/12/15 全球购物
META-INF文件夹中的MANIFEST.MF的作用
2016/06/21 面试题
收银员岗位职责
2014/02/07 职场文书
青蓝工程实施方案
2014/03/27 职场文书
《美丽的丹顶鹤》教学反思
2014/04/22 职场文书
五五普法心得体会
2014/09/04 职场文书
个人剖析材料范文
2014/09/30 职场文书
法人代表证明书格式
2014/10/01 职场文书
2014年度个人工作总结范文
2015/03/09 职场文书
中秋节祝酒词
2015/08/12 职场文书
Python 如何实现文件自动去重
2021/06/02 Python