在Javascript中,最玄妙的特性之一,就是this的指向玄幻莫测,一会儿指向这一会儿指向那,让初学者十分伤脑筋。

本文总结一下,方便初学者掌握奥妙之处,同时方便老鸟温故而知新。

首先,看一段代码:

var module = {
x: 42,
getX: function() {
return this.x;
}
}
console.log(module.getX());//
var unboundGetX = module.getX;
console.log(unboundGetX()); //undefined

一个输出42,一个输出undefined,这是为何呢??

var unboundGetX = module.getX;

相当于是

var unboundGetX = function(){
return this.x;
}

这是不是就比较容易懂了?OK,引出结论:

函数体内的this指向执行上下文环境(Excution Context)

没错,this的定义就是就这么简单。

那么该怎么找上下文环境呢?调用函数时,该函数名往左由“·”符号连起来的对象,就是执行上下文

console.log(module.getX());

很明显,这句函数调用,是通过module对象调用的,那么上下文环境就是module,this指向module,module.x=42,所以输出42;

console.log(unboundGetX());

而上面这句,调用unboundGetX()时没有通过“·”指明是通过谁来调用的,那么this就全局执行上下文,很明显func函数是在全局执行上下文下定义的,全局对象是window,所以this指向window,而window.x未定义,当然返回undefined。

OK,讲到这里,最重要的内容基本上就讲完了。

放一段代码,大家利用我讲的知识,去思考为什么是这个运行结果?

var name = "window"

function func() {
console.log(this.name);
} var TB = {
name: "object",
test(fn) {
fn && fn();
return function() {
return this.name;
}
}
}
console.log(TB.test(func)());

最后一些tips: 

1)严格模式下,函数体内的this是undefined。
2)new Foo()的形式生成对象的时候,Foo函数内部的this指向该对象。
3)apply、call、bind 允许切换函数执行的上下文环境(context),即 this 绑定的对象,可以将 this 引用到任何对象。
4)在ES6中,当使用箭头函数(=>)时,this的指向总是指向定义它的上下文环境(context)

彻底搞懂Javascript的this的更多相关文章

  1. 来一轮带注释的demo,彻底搞懂javascript中的replace函数

    javascript这门语言一直就像一位带着面纱的美女,总是看不清,摸不透,一直专注服务器端,也从来没有特别重视过,直到最近几年,javascript越来越重要,越来越通用.最近和前端走的比较近,借此 ...

  2. 一张图彻底搞懂JavaScript的==运算

    一张图彻底搞懂JavaScript的==运算 来源 https://zhuanlan.zhihu.com/p/21650547 PS:最后,把图改了一下,仅供娱乐 : ) 大家知道,==是JavaSc ...

  3. 彻底搞懂Javascript的“==”

    本文转载自:@manxisuo的<通过一张简单的图,让你彻底地.永久地搞懂JS的==运算>. 大家知道,==是JavaScript中比较复杂的一个运算符.它的运算规则奇怪,容让人犯错,从而 ...

  4. 彻底搞懂JavaScript中的继承

    你应该知道,JavaScript是一门基于原型链的语言,而我们今天的主题 -- "继承"就和"原型链"这一概念息息相关.甚至可以说,所谓的"原型链&q ...

  5. 一张图带你搞懂Javascript原型链关系

    在某天,我听了一个老师的公开课,一张图搞懂了原型链. 老师花两天时间理解.整理的,他讲了两个小时我们当时就听懂了. 今天我把他整理出来,分享给大家.也让我自己巩固加深一下. 就是这张图: 为了更好的图 ...

  6. 一张图搞懂 Javascript 中的原型链、prototype、__proto__的关系 转载加自己的总结

    1. JavaScript内置对象 所谓的内置对象 指的是:JavaScript本身就自己有的对象 可以直接拿来就用.例如Array String 等等.JavaScript一共有12内置对象    ...

  7. 一张图轻松搞懂javascript event对象的clientX,offsetX,screenX,pageX区别

    总是会被javascript的event对象的clientX,offsetX,screenX,pageX 弄得头晕,于是决定做个图来区分一下(画得我手那个酸呀....) 先总结下区别: event.c ...

  8. 你真的已经搞懂JavaScript了吗?

    题目一: if (!("a" in window)) { var a = 1; } alert(a); 题目二: var a = 1, b = function a(x) { x ...

  9. 彻底搞懂javascript中的match, exec的区别

    在工作中经常发现一些同学把这两个方法搞混,以致把自己弄的很郁闷.所以我和大家一起来探讨一下这两个方法的奥妙之处吧. 我们分以下几点来讲解: 相同点: 1.两个方法都是查找符合条件的匹配项,并以数组形式 ...

  10. 五个小例子教你搞懂 JavaScript 作用域问题

    众所周知,JavaScript 的作用域和其他传统语言(类C)差别比较大,掌握并熟练运用JavaScript 的作用域知识,不仅有利于我们阅读理解别人的代码,也有助于我们编写自己的可靠代码. 下面笔者 ...

随机推荐

  1. kubernetes集群内通过endpoint访问外部服务

    kubernetes内的服务访问集群外独立的服务最好通过endpoint方式,例如MySQL 1.创建mysql-service.yaml apiVersion: v1 kind: Service m ...

  2. 安装gcc-c++报错解决办法

    问题 每次安装依赖包gcc-c++的时候,经常会遇到包如下错误   Error: Package: libstdc++-devel--.el7_4..x86_64 (ultra-centos-7.4- ...

  3. OEL7.6源码安装MYSQL5.7

    首先官网下载安装包https://dev.mysql.com/downloads/mysql/5.7.html#downloads 然后上传解压至/usr/local目录 [root@localhos ...

  4. 使用mysql数据库过程中常用的命令

    1.添加用户:GRANT USAGE ON . TO 'user01'@'localhost' IDENTIFIED BY '123456' WITH GRANT OPTION; 2.列出mysql数 ...

  5. python 文本全选

    这个是一个控制框有效果 # encoding: utf-8 from Tkinter import * def printentry(event): print("click on" ...

  6. 常用dos命令(2)

    文件管理 type 显示文本文件的内容. copy 将一份或多份文件复制到另一个位置. del 删除一个或数个文件. move 移动文件并重命名文件和目录.(Windows XP Home Editi ...

  7. ORA-00923: FROM keyword not found where expected

    网上搜索这类错误还是挺多的,只提供我遇到的一种情景. 本地数据库环境:Oracle10g 导入别人的项目后,有一段SQL查询总是报如下错误信息: Cause: java.sql.SQLExceptio ...

  8. mybatis学习3

    parameterType(输入类型) 传递简单类型::使用#{}占位符,或者${}进行sql拼接 传递pojo对象: Mybatis使用ognl表达式解析对象字段的值,#{}或者${}括号中的值为p ...

  9. eclipse scala语法用java检验 报错问题

    传送门 https://stackoverflow.com/questions/8522149/eclipse-not-recognizing-scala-code 还是 直接用eclipse的 sc ...

  10. postfix发邮件失败,日志和postqueue -p提示Connection refused

    1. postfix服务未启动 2. /etc/postfix/main.cf文件中未设置inet_interfaces = all