再次谈论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 相关文章推荐
如何解决Jquery库及其他库之间的$命名冲突
Sep 15 Javascript
查找页面中所有类为test的结点的方法
Mar 28 Javascript
JavaScript中对象property的删除方法介绍
Dec 30 Javascript
浅谈javascript函数式编程
Sep 06 Javascript
JavaScript基本的输出和嵌入式写法教程
Oct 20 Javascript
jQuery EasyUI之DataGrid使用实例详解
Jan 04 Javascript
jQuery使用ajax跨域获取数据的简单实例
May 18 Javascript
一个极为简单的requirejs实现方法
Oct 20 Javascript
JS去掉字符串前后空格或去掉所有空格的用法
Mar 25 Javascript
微信小程序提取公用函数到util.js及使用方法示例
Jan 10 Javascript
koa中间件核心(koa-compose)源码解读分析
Jun 15 Javascript
如何在JavaScript中正确处理变量
Dec 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与MYSQL中UTF8编码的中文排序实例
2014/10/21 PHP
php实现parent调用父类的构造方法与被覆写的方法
2015/02/11 PHP
laravel 解决Validator使用中出现的问题
2019/10/25 PHP
jQuery ul标签下拉菜单演示代码
2010/12/11 Javascript
js弹出层之1:JQuery.Boxy (二)
2011/10/06 Javascript
js Form.elements[i]的使用实例
2011/11/13 Javascript
jquery 如何动态添加、删除class样式方法介绍
2012/11/07 Javascript
Javascript 鼠标移动上去小三角形滑块缓慢跟随效果
2013/04/26 Javascript
Extjs4 类的定义和扩展实例
2013/06/28 Javascript
javascript 判断整数方法分享
2014/12/16 Javascript
jQuery实现按钮点击遮罩加载及处理完后恢复的效果
2016/06/07 Javascript
springMVC + easyui + $.ajaxFileUpload实现文件上传注意事项
2017/04/23 Javascript
JavaScript实现打地鼠小游戏
2020/04/23 Javascript
薪资那么高的Web前端必看书单
2017/10/13 Javascript
vue-awesome-swiper滑块插件使用方法详解
2017/11/27 Javascript
jQuery实现获取form表单内容及绑定数据到form表单操作分析
2018/07/03 jQuery
Vue自定义指令封装节流函数的方法示例
2018/07/09 Javascript
关于element-ui的隐藏组件el-scrollbar的使用
2019/05/29 Javascript
在mpvue框架中使用Vant WeappUI组件库的注意事项【推进】
2019/06/09 Javascript
JavaScript中Object、map、weakmap的区别分析
2020/12/15 Javascript
Python下的常用下载安装工具pip的安装方法
2015/11/13 Python
python搭建微信公众平台
2016/02/09 Python
用python处理图片实现图像中的像素访问
2018/05/04 Python
Python with用法:自动关闭文件进程
2019/07/10 Python
python自动保存百度盘资源到百度盘中的实例代码
2019/08/26 Python
PyQt5中QTableWidget如何弹出菜单的示例代码
2020/02/23 Python
Python实现汇率转换操作
2020/05/03 Python
Python基于pandas爬取网页表格数据
2020/05/11 Python
Pytho爬虫中Requests设置请求头Headers的方法
2020/09/22 Python
HTML5 HTMLCollection和NodeList的区别详解
2020/04/29 HTML / CSS
英国最大的手表网站:The Watch Hut
2017/03/31 全球购物
俄罗斯名牌服装网上商店:UNIQUE FABRIC
2019/07/25 全球购物
Noon埃及:埃及在线购物
2019/11/26 全球购物
Zalando Lounge瑞士:时尚与生活方式购物俱乐部
2020/03/12 全球购物
如何查找网页漏洞
2016/06/22 面试题
为自己工作观后感
2015/06/11 职场文书