再次谈论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+dom树型菜单类,希望朋友们一起进步
May 03 Javascript
jquery实现文本框鼠标右击无效以及不能输入的代码
Nov 05 Javascript
javascript阻止浏览器后退事件防止误操作清空表单
Nov 22 Javascript
JS与C#编码解码
Dec 03 Javascript
超简单JS二级、多级联动的简单实例
Feb 18 Javascript
引用其它js时如何同时处理多个window.onload事件
Sep 02 Javascript
原生js和jquery实现图片轮播特效
Apr 23 Javascript
js禁止浏览器页面后退功能的实例(推荐)
Sep 01 Javascript
jfinal与bootstrap的登出实战详解
Nov 27 Javascript
JS实现的文字间歇循环滚动效果完整示例
Feb 13 Javascript
angularJs自定义过滤器实现手机号信息隐藏的方法
Oct 08 Javascript
vantUI 获得piker选中值的自定义ID操作
Nov 04 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
图片存储与浏览一例(Linux+Apache+PHP+MySQL)
2006/10/09 PHP
解析PHP实现多进程并行执行脚本
2013/06/18 PHP
解析PHP提交后跳转
2013/06/23 PHP
php实现图片上传并进行替换操作
2016/03/15 PHP
php框架CodeIgniter使用redis的方法分析
2018/04/13 PHP
基于jquery的jqDnR拖拽溢出的修改
2011/02/12 Javascript
设为首页加入收藏兼容360/火狐/谷歌/IE等主流浏览器的代码
2013/03/26 Javascript
一种新的javascript对象创建方式Object.create()
2015/12/28 Javascript
Javascript之面向对象--封装
2016/12/02 Javascript
Express与NodeJs创建服务器的两种方法
2017/02/06 NodeJs
javascript自执行函数
2017/02/10 Javascript
浅谈Vue初学之props的驼峰命名
2018/07/19 Javascript
js防抖和节流的深入讲解
2018/12/06 Javascript
JavaScript定时器常见用法实例分析
2019/11/15 Javascript
JS实现音乐钢琴特效
2020/01/06 Javascript
[44:33]EG vs Liquid 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
[51:17]完美世界DOTA2联赛循环赛Inki vs DeMonsTer 第二场 10月30日
2020/10/31 DOTA
python编写的最短路径算法
2015/03/25 Python
python实现一个简单的ping工具方法
2019/01/31 Python
python中几种自动微分库解析
2019/08/29 Python
Python 防止死锁的方法
2020/07/29 Python
Silk’n激光脱毛器官网:silkn.com
2016/10/06 全球购物
Draper James官网:知名演员瑞茜·威瑟斯彭所创品牌
2017/10/25 全球购物
Vichy薇姿加拿大官网:法国药妆,全球专业敏感肌护肤领先品牌
2018/07/11 全球购物
体验完美剃须:The Art of Shaving
2018/08/06 全球购物
美国精油公司:Plant Therapy
2019/05/17 全球购物
幼儿教师自我鉴定
2013/11/02 职场文书
计算机学生的自我评价分享
2014/02/18 职场文书
2014国培学习感言
2014/03/05 职场文书
韩语专业职业生涯规划范文:成功之路就在我们脚下
2014/09/11 职场文书
2014年留守儿童工作总结
2014/12/10 职场文书
2015年幼儿园后勤工作总结
2015/04/25 职场文书
2015年度企业工作总结
2015/05/21 职场文书
2016学习全国教书育人楷模先进事迹心得体会
2016/01/21 职场文书
党风廉政建设心得体会
2019/05/21 职场文书
elasticSearch-api的具体操作步骤讲解
2021/06/28 Java/Android