一直对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中的this的更多相关文章

  1. javascript中的原型和继承

    javascript一直是初学者口中的难点,甚至一些有些许工作经验的人也不太明白其中的原理,而我就是那个初学者,前段时间在阮一峰老师的博客上看了一篇文章<javascript继承机制的设计思想& ...

  2. javascript中值传递与值引用的研究

    今天重新看了一下<javascript高级程序设计>,其中讲到了javascript中的值传递和值引用,所以就自己研读了一下,但是刚开始没有明白函数中的参数只有值传递,有的场景好像参数是以 ...

  3. 快速入门上手JavaScript中的Promise

    当我还是一个小白的时候,我翻了很多关于Promise介绍的文档,我一直没能理解所谓解决异步操作的痛点是什么意思 直到我翻了谷歌第一页的所有中文文档我才有所顿悟,其实从他的英文字面意思理解最为简单粗暴 ...

  4. javascript中的Array对象 —— 数组的合并、转换、迭代、排序、堆栈

    Array 是javascript中经常用到的数据类型.javascript 的数组其他语言中数组的最大的区别是其每个数组项都可以保存任何类型的数据.本文主要讨论javascript中数组的声明.转换 ...

  5. javascript中的this与函数讲解

    前言 javascript中没有块级作用域(es6以前),javascript中作用域分为函数作用域和全局作用域.并且,大家可以认为全局作用域其实就是Window函数的函数作用域,我们编写的js代码, ...

  6. JavaScript 中的数据类型

    Javascript中的数据类型有以下几种情况: 基本类型:string,number,boolean 特殊类型:undefined,null 引用类型:Object,Function,Date,Ar ...

  7. javascript中的操作符详解1

    好久没有写点什么了,根据博主的技术,仍然写一点javascript新手入门文章,接下来我们一起来探讨javascript的操作符. 一.前言 javascript中有许多操作符,但是许多初学者并不理解 ...

  8. 掌握javascript中的最基础数据结构-----数组

    这是一篇<数据结构与算法javascript描述>的读书笔记.主要梳理了关于数组的知识.部分内容及源码来自原作. 书中第一章介绍了如何配置javascript运行环境:javascript ...

  9. javascript中变量提升的理解

    网上找了两个经典的例子 var foo = 1; function bar() { if (!foo) { var foo = 10; } alert(foo); } bar(); // 10 var ...

随机推荐

  1. HDU 1166 敌兵布阵 (数状数组,或线段树)

    题意:... 析:可以直接用数状数组进行模拟,也可以用线段树. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000&quo ...

  2. LINUX RHEL AS 4 + ORACLE10G安装详解

    第一部分:LINUX RHEL AS 4 安装 运行提示: 1)按键盘的前后键可以调节光标所在的位置 2)在选项前面的括号中打上*号或者去掉*号,选中这条选项用空格键操作 3)在vi编辑文件时,键盘按 ...

  3. [DNX]解决dnu restore时找不到Newtonsoft.Json的问题

    在Mac上用最新版的dnx 1.0.0-beta5-11855进行dnu restore,出现下面的错误: System.IO.FileNotFoundException: Could not loa ...

  4. 转:判断DATASET是否为空

    http://blog.sina.com.cn/jiangshuqin2010 1,if(ds == null) 这是判断内存中的数据集是否为空,说明DATASET为空,行和列都不存在!! 2,if( ...

  5. 仿花田:内部相亲网站 意中人(Asp.net MVC,Bootstrap2)

    起因: 那是七月份了,看见单身的同事在上花田网,当时觉得风格比较清新,还没有世纪佳缘等那些网站那么商业化,加上又看到了bootrstrap,于是就想做个demo出来玩玩.中间自己又在做其他的事情,和w ...

  6. Android布局中涉及的一些属性

    Android:gravity属性 线性布局常见的就是利用LinearLayout进行布局,其中有个比较重要的属性就是android:gravity,在官方文档中是这么描述这个属性的:指定一个元素怎么 ...

  7. JSON相关(一):JSON.parse()和JSON.stringify()

    parse用于从一个字符串中解析出json对象,如 var str = '{"name":"huangxiaojian","age":&qu ...

  8. HTML5基础-Mark标签高亮显示文本

    1.mark标签使用 <mark></mark> 2.mark作用 使用mark标签元素,可以高亮显示文档中的文字以达到醒目的效果. 3.mark使用代码 <!DOCTY ...

  9. [Python爬虫] Selenium获取百度百科旅游景点的InfoBox消息盒

    前面我讲述过如何通过BeautifulSoup获取维基百科的消息盒,同样可以通过Spider获取网站内容,最近学习了Selenium+Phantomjs后,准备利用它们获取百度百科的旅游景点消息盒(I ...

  10. JSP JSTL EL

    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> Html代码 复制代 ...