再次谈论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 设置选中行的样式的实现代码
May 24 Javascript
jquery 如何动态添加、删除class样式方法介绍
Nov 07 Javascript
js简单实现用户注册信息的校验代码
Nov 15 Javascript
jQuery实现复选框成对选择及对应取消的方法
Mar 03 Javascript
JS函数的几种定义方式分析
Dec 17 Javascript
js类式继承与原型式继承详解
Apr 07 Javascript
Bootstrap进度条组件知识详解
May 01 Javascript
javascript实现二叉树遍历的代码
Jun 08 Javascript
分析JS单线程异步io回调的特性
Dec 01 Javascript
详解搭建es6+devServer简单开发环境
Sep 25 Javascript
JavaScript&quot;模拟事件&quot;的注意要点详解
Feb 13 Javascript
JavaScript继承的三种方法实例
May 12 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
收音机另类DIY - 纸巾盒做外壳
2021/03/02 无线电
PHP的explode和implode的使用说明
2011/07/17 PHP
浅析PKI加密解密 OpenSSL
2013/07/01 PHP
简单谈谈PHP vs Node.js
2015/07/17 PHP
PHP通过加锁实现并发情况下抢码功能
2016/08/10 PHP
php curl上传、下载、https登陆实现代码
2017/07/23 PHP
PHP 中 var_export、print_r、var_dump 调试中的区别
2018/06/19 PHP
jQuery图片轮播的具体实现
2013/09/11 Javascript
一个小例子解释如何来阻止Jquery事件冒泡
2014/07/17 Javascript
jQuery实现隔行背景色变色
2014/11/24 Javascript
使用jQuery在移动页面上添加按钮和给按钮添加图标
2015/12/04 Javascript
手机图片预览插件photoswipe.js使用总结
2016/08/25 Javascript
jquery操作checkbox火狐下第二次无法勾选的解决方法
2016/10/10 Javascript
js Canvas实现的日历时钟案例分享
2016/12/25 Javascript
iview同时验证多个表单问题总结
2018/09/29 Javascript
微信小程序实现星星评价效果
2018/11/02 Javascript
JS实现的简单tab切换功能完整示例
2019/06/20 Javascript
[01:08:10]2014 DOTA2国际邀请赛中国区预选赛 SPD-GAMING VS LGD-CDEC
2014/05/22 DOTA
Python实现的批量下载RFC文档
2015/03/10 Python
Python自动重试HTTP连接装饰器
2015/04/28 Python
简介Python的collections模块中defaultdict类型的用法
2016/07/07 Python
使用pandas读取csv文件的指定列方法
2018/04/21 Python
Python3操作Excel文件(读写)的简单实例
2019/09/02 Python
Python找出列表中出现次数最多的元素三种方式
2020/02/24 Python
分享unittest单元测试框架中几种常用的用例加载方法
2020/12/02 Python
python工具——Mimesis的简单使用教程
2021/01/16 Python
css3背景_动力节点Java学院整理
2017/07/11 HTML / CSS
英国玛莎百货美国官网:Marks & Spencer美国
2018/11/06 全球购物
澳大利亚窗帘商店:Curtain Wonderland
2019/12/01 全球购物
Boolean b = new Boolean(“abcde”); 会编译错误码
2013/11/27 面试题
党的群众路线教育实践活动组织生活会发言材料
2014/10/17 职场文书
2015大学自主招生自荐信范文
2015/03/04 职场文书
夫妻吵架保证书
2015/05/08 职场文书
羊脂球读书笔记
2015/06/30 职场文书
升学宴家长致辞
2015/07/27 职场文书
2016党员学习《反对自由主义》心得体会
2016/01/22 职场文书