记录js学习之this用法
一直对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的时候,绑定事件的时候遇到的坑,那时候只知道这么写,不知道怎么回事,今天突然感觉豁然开朗。希望对大家有所帮助。
记录js学习之this用法的更多相关文章
- Ext JS学习第十六天 事件机制event(一) DotNet进阶系列(持续更新) 第一节:.Net版基于WebSocket的聊天室样例 第十五节:深入理解async和await的作用及各种适用场景和用法 第十五节:深入理解async和await的作用及各种适用场景和用法 前端自动化准备和详细配置(NVM、NPM/CNPM、NodeJs、NRM、WebPack、Gulp/Grunt、G
code&monkey Ext JS学习第十六天 事件机制event(一) 此文用来记录学习笔记: 休息了好几天,从今天开始继续保持更新,鞭策自己学习 今天我们来说一说什么是事件,对于事件 ...
- 我的three.js学习记录(二)
通过上一篇文章我的three.js学习记录(一)基本上是入门了three.js,但是这不够3D,这次我希望能把之前做的demo弄出来,然后通过例子来分析操作步骤. 1. 示例 上图是之前做的一个dem ...
- 我的three.js学习记录(三)
此次的亮点不是three.js的3d部分,而是通过调用摄像头然后通过摄像头的图像变化进行简单的判断后进行一些操作.上篇中我通过简单的示例分析来学习three.js,这次是通过上一篇的一些代码来与摄像头 ...
- vue.js学习记录
vue.js学习记录 文章已同步我的github笔记https://github.com/ymblog/blog,欢迎大家加star~~ vue实例 生命周期 beforeCreate:不能访问thi ...
- [转]passport.js学习笔记
概述 passport.js是Nodejs中的一个做登录验证的中间件,极其灵活和模块化,并且可与Express.Sails等Web框架无缝集成.Passport功能单一,即只能做登录验证,但非常强大, ...
- 【Knockout.js 学习体验之旅】(3)模板绑定
本文是[Knockout.js 学习体验之旅]系列文章的第3篇,所有demo均基于目前knockout.js的最新版本(3.4.0).小茄才识有限,文中若有不当之处,还望大家指出. 目录: [Knoc ...
- 【Knockout.js 学习体验之旅】(1)ko初体验
前言 什么,你现在还在看knockout.js?这货都已经落后主流一千年了!赶紧去学Angular.React啊,再不赶紧的话,他们也要变out了哦.身旁的90后小伙伴,嘴里还塞着山东的狗不理大蒜包, ...
- js模块化开发——require.js学习总结
1.为什么使用require.js 作为命名空间: 作为命名空间使用: 异步加载js,避免阻塞,提高性能: js通过require加载,不必写很多script 2.require.js的加载 requ ...
- JS中event.keyCode用法及keyCode对…
js中event.keyCode用法及keyCode对照表 标签: javascriptJavaScriptJavascriptjavaScript 2012-12-11 15:11 HTML Jav ...
随机推荐
- TCP/IP BOOKS
TCP/IP Fundamentals for Microsoft Windows: Overview https://technet.microsoft.com/en-us/library/bb72 ...
- js实现页面局部弹窗打印
原文出自:http://www.haorooms.com/post/css3media 在网页中经常看到有打印功能,点击之后,只针对特定区域进行的打印.网上看了一下,大体上有2中实现方法,一种是用cs ...
- 免装版tomcat注册成windows系统服务方法
如果一台服务器要部署两个应用,而且又各自不受影响的话,只能使用两个端口两个tomcat分别管理 在这里吐槽一下tomcat,为毛停止服务就把所有应用都停了,更新其中一个,就要把所有的都停了,然后更新完 ...
- Head First 设计模式之观察者模式(Observer Pattern)
前言: 这一节开始学习观察者模式,开始讲之前会先像第一节那样通过一个应用场景来引入该模式.具体场景为:气象站提供了一个WeatherData对象,该对象可以追踪获取天气的温度.气压.湿度信息,Weat ...
- 第一个FPGA工程----点亮开发板上的3个LED灯
第一个FPGA工程----点亮开发板上的3个LED灯 1.新建FPGA工程 开启Quartus2的画面 File--New Project Wizard..指定工程的路径与工程名 指定所使用的FPGA ...
- Best Practices for Performance_4.Optimizing Battery Life 获取充电状态、电池信息,"sticky"类型的广播
http://developer.android.com/training/monitoring-device-state/index.htmlhttp://developer.android.com ...
- AVD Manager
启动AVD Manager会弹出下面的窗口: 然后点击右侧的Create来新建一个模拟器,创建一个模拟器,取名Phone,然后选择设备屏幕尺寸,SDK的大小. 创建完成后,选中刚刚创建的模拟器,然后点 ...
- npoi上传xlsx文件,并读取数据
视图 public PartialViewResult UploadIndex() { return PartialView(); } <div> <fieldset style=& ...
- LogStash的Filter的使用
最近在项目中使用LogStash做日志的采集和过滤,感觉LogStash还是很强大的. input { file{ path => "/XXX/syslog.txt" sta ...
- Access自动编号的初始值设置及重置编号
项目上需要在Access数据库,发现自动编号的列无法设置初始值和步长,但是可以使用SQL语句来设置它. 方法如下: ALTER TABLE tableName ALTER COLUMN ID COUN ...