再次谈论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 相关文章推荐
java、javascript实现附件下载示例
Aug 14 Javascript
Javascript中的关键字和保留字整理
Oct 16 Javascript
异步安全加载javascript文件的方法
Jul 21 Javascript
jquery无限级联下拉菜单简单实例演示
Nov 23 Javascript
javascript编程异常处理实例小结
Nov 30 Javascript
全面了解javascript中的错误处理机制
Jul 18 Javascript
微信小程序获取循环元素id以及wx.login登录操作
Aug 17 Javascript
利用JavaScript的%做隔行换色的实例
Nov 25 Javascript
vue.js实现标签页切换效果
Jun 07 Javascript
微信小程序数据分析之自定义分析的实现
Aug 17 Javascript
html2canvas属性和使用方法以及如何使用html2canvas将HTML内容写入Canvas生成图片
Jan 12 Javascript
原生js实现购物车
Sep 23 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开发工具之vs2005图解
2008/01/12 PHP
摘自织梦CMS中的图片处理类
2015/08/08 PHP
php二维码生成
2015/10/19 PHP
PHP preg_match实现正则表达式匹配功能【输出是否匹配及匹配值】
2017/07/19 PHP
PHP学习记录之数组函数
2018/06/01 PHP
PHP判断访客是否手机端(移动端浏览器)访问的方法总结【4种方法】
2019/03/27 PHP
php变量与字符串的增删改查操作示例
2020/05/07 PHP
WordPress JQuery处理沙发头像
2009/06/22 Javascript
JavaScript中把数字转换为字符串的程序代码
2013/06/19 Javascript
IE中的File域无法清空使用jQuery重设File域
2014/04/24 Javascript
Nodejs中读取中文文件编码问题、发送邮件和定时任务实例
2015/01/01 NodeJs
基于Bootstrap使用jQuery实现简单可编辑表格
2016/05/04 Javascript
详解Node.js:events事件模块
2016/11/24 Javascript
Node.js使用NodeMailer发送邮件实例代码
2017/03/06 Javascript
Vue2.0如何发布项目实战
2017/07/27 Javascript
React-Router如何进行页面权限管理的方法
2017/12/06 Javascript
JQuery特殊效果和链式调用操作示例
2019/05/13 jQuery
JavaScript函数式编程(Functional Programming)高阶函数(Higher order functions)用法分析
2019/05/22 Javascript
Vue-cli打包后部署到子目录下的路径问题说明
2020/09/02 Javascript
Django在Win7下的安装及创建项目hello word简明教程
2014/07/14 Python
Python单元测试框架unittest简明使用实例
2015/04/13 Python
用Python的Django框架编写从Google Adsense中获得报表的应用
2015/04/17 Python
Python 实现淘宝秒杀的示例代码
2018/01/02 Python
人脸识别经典算法一 特征脸方法(Eigenface)
2018/03/13 Python
python抓取需要扫微信登陆页面
2019/04/29 Python
python 普通克里金(Kriging)法的实现
2019/12/19 Python
python 如何将office文件转换为PDF
2020/09/22 Python
优秀员工评语
2014/02/10 职场文书
文秘大学生求职信
2014/02/25 职场文书
出纳试用期自我鉴定
2014/04/07 职场文书
党支部综合考察材料
2014/05/19 职场文书
Python Numpy之linspace用法说明
2021/04/17 Python
python实现监听键盘
2021/04/26 Python
详解MongoDB的条件查询和排序
2021/06/23 MongoDB
带你了解CSS基础知识,样式
2021/07/21 HTML / CSS
python中的3种定义类方法
2021/11/27 Python