JavaScript之this释疑
近期进修JavaScript,看了“You Don't Know JS”这本书,认为是本JavaScript内功上乘心法,有一定JavaScript基础朋友一定要看看(不推荐入门小朋友看。怕走火入魔)。
作者知识渊博,理解透彻。行文流畅,案例经典,绝对的大神级人物。
本文将对书中关于JavaScript中this的讲述做一个小结,也会增加一些自己的理解。
算是抛砖。以期引玉。
JavaScript里面this究竟是什么?
this是一个标志符,指向某一个对象或者undefined。
JavaScript是什么?一门编程语言;编程语言干嘛的?编写代码。为啥编写代码?运行代码,命令计算机处理事情。好了,写好的JavaScript代码是用来运行的,而且JavaScript Engine会指定一个运行环境(Execution Environment)。运行环境非常复杂,简单来说。能够理解为一个运行数据容器(JavaScript里面能够叫作对象)。JavaScript的代码(一系列的语句)会在两个地方运行,全局区域,以及函数(Function)内部。
this就是运行环境里面的一个属性(Property),指向运行所针对的某一个对象。
为了描写叙述清楚this和运行环境的关系,简单来说。能够表述例如以下:
Executor_Environment = {
invoke_stack:[statck1, statck2, ...],
params: [param1, param2, ...],
scope_chain:[scop1, scope2, ...],
this: execute_ object,
...
}
继续追问下去。
this指向的对象又是什么?函数调用的时候,this指向的对象是函数执行的上下文,一个目标对象。是执行时由JavaScript Engine动态绑定的。
函数里面this的4种场景
函数里面this的绑定情况有4种。以下将逐一介绍。
原书作者强调某些场景下四种情况可能会有某两个或者三个都适用,须要排列效用的强度大小,这一点。我不太赞同,我认为还是都能够归并到某一种场景的。
newkeyword
JavaScript里面newkeyword后接一个Function调用,会新创建一个对象,运行Function的时候,JavaScript Engine会把新创建的对象赋值给this,即此时this指向新创建的对象。以下给出两个样例:
new样例1:
function Func1(){
this.a = 3;
} var a1 = new Func1();
console.log(a1.a); // 3
new样例2:
function Func2(){
this.a = 3;
return {};
} var a2 = new Func2();
console.log(a2.a); // undefined
后面的样例是想说,假设Function里面有return语句。那么new语句新创建的对象会被丢弃!
call和apply
call和apply的作用就是强行指定Function里面this所应该指向的对象。
call的一个小样例:
function sayHi(){
console.log("Hi,"+ this.name);
} var p = {name:"Kevin", age: 26}; sayHi.call(p);
作为对象的属性调用
这里有两层意思。Function是对象的一个属性,通过对象来訪问Function并马上调用。这样的情况下,Function里面的this指向该对象。
样例:
function sayHi(){
console.log("Hi,"+ this.name);
} var p = {name:"Kevin", age: 26, hi: sayHi}; p.hi();
直接调用Function
通过Function的名字,直接调用Function。通常JavaScript Engine会把Global绑定给this。浏览器里面Global是window。只是据说"use strict"情况下,this指向undefined(严格来说undefined在JavaScript里面不是对象)。
Function直接调用的小样例:
function sayHi(){
console.log("Hi,"+ this.name);
console.log(this);
} var name = "Just Joke"; sayHi(); // output:Hi, Just Joke
// followed global object, which contain name, sayHi。
全局区域里面的this代表什么
说实话。我仅仅是推測。全局区域的语句也须要一个运行环境,该运行环境也有一个this标志符,指向Global对象。浏览器里面就是window。这一点“You Don't Know JS”原书中没有提及。
全局区域输入下面代码试试:
var name = "James";
console.log("I am "+ this.name); // I am James
參考链接
JavaScript之this释疑的更多相关文章
- 从javascript发展说到vue
Vue是基于javascript的一套MVVC前端框架,在介绍vue之前有必要先大体介绍下javascript产生背景及发展的历史痕迹.前端MVVC模式等,以便于大家更好的理解为什么会有vue/rea ...
- 你不知道的javaScript笔记(5)
原生函数 常用的原生函数 String() Number() Boolean() Array() Object() Function() RegExp() Date() Error() Symbol( ...
- JavaScript之父Brendan Eich,Clojure 创建者Rich Hickey,Python创建者Van Rossum等编程大牛对程序员的职业建议
软件开发是现时很火的职业.据美国劳动局发布的一项统计数据显示,从2014年至2024年,美国就业市场对开发人员的需求量将增长17%,而这个增长率比起所有职业的平均需求量高出了7%.很多人年轻人会选择编 ...
- javascript中的Array对象 —— 数组的合并、转换、迭代、排序、堆栈
Array 是javascript中经常用到的数据类型.javascript 的数组其他语言中数组的最大的区别是其每个数组项都可以保存任何类型的数据.本文主要讨论javascript中数组的声明.转换 ...
- Javascript 的执行环境(execution context)和作用域(scope)及垃圾回收
执行环境有全局执行环境和函数执行环境之分,每次进入一个新执行环境,都会创建一个搜索变量和函数的作用域链.函数的局部环境不仅有权访问函数作用于中的变量,而且可以访问其外部环境,直到全局环境.全局执行环境 ...
- 探究javascript对象和数组的异同,及函数变量缓存技巧
javascript中最经典也最受非议的一句话就是:javascript中一切皆是对象.这篇重点要提到的,就是任何jser都不陌生的Object和Array. 有段时间曾经很诧异,到底两种数据类型用来 ...
- 读书笔记:JavaScript DOM 编程艺术(第二版)
读完还是能学到很多的基础知识,这里记录下,方便回顾与及时查阅. 内容也有自己的一些补充. JavaScript DOM 编程艺术(第二版) 1.JavaScript简史 JavaScript由Nets ...
- 《Web 前端面试指南》1、JavaScript 闭包深入浅出
闭包是什么? 闭包是内部函数可以访问外部函数的变量.它可以访问三个作用域:首先可以访问自己的作用域(也就是定义在大括号内的变量),它也能访问外部函数的变量,和它能访问全局变量. 内部函数不仅可以访问外 ...
- JavaScript权威指南 - 函数
函数本身就是一段JavaScript代码,定义一次但可能被调用任意次.如果函数挂载在一个对象上,作为对象的一个属性,通常这种函数被称作对象的方法.用于初始化一个新创建的对象的函数被称作构造函数. 相对 ...
随机推荐
- luogu2508 [HAOI2008]圆上的整点
题目大意 给出\(r\),求圆\(x^2+y^2=r^2\)上坐标均为整数的点数.\(n<=2,000,000,000\) 总体思路 我们看到这个数据大小,还是个数学题,想到这个的时间复杂度应当 ...
- Intel 的 MKL是可以用来训练的——官方的实验也提到了训练
TensorFlow如何充分使用所有CPU核数,提高TensorFlow的CPU使用率,以及Intel的MKL加速 转载 2017年09月07日 16:34:58 标签: cpu / gpu 转载 ...
- [NOIP 2007] 树网的核
[题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=1999 [算法] 树的直径 + 单调队列 [代码] #include<bits/ ...
- MySql查询系统时间,SQLServer查询系统时间,Oracle查询系统时间
转自:https://blog.csdn.net/haleyliu123/article/details/70927668/ MySQL查询系统时间 第一种方法:select current_date ...
- 根据日期获取,x岁x月x天
c#: DateTime startDate = new DateTime(); DateTime endDate = new DateTime(); ; ; ; if (endDate.Month& ...
- CI中的超级对象
CI中的超级对象就是当前控制器对象,它提供了很多属性,可以通过var_dump($this)打印所有的超级对象: load可以理解为一个加载器,加载了很多功能,可以理解为当你使用 $this -> ...
- Python 之 面向对象(一)
一.dir内置函数 在标识符/数据后输入一个.,然后按下TAB键,ipython会 提示该对象能够调用的方法列表 使用内置函数dir传入标识符/数据后,可以查看对象内所有的属性及方法 #查看注释 de ...
- Struts2学习笔记 - Part.01
1.关于Struts2中的struts.xml文件中action设置 <!-- 它是一个通用action,此处的*表明它可以处理任意的请求--> <action name=" ...
- Xcode8 NSLog打印json不完整的解决方案
解决方案:自定义宏,通过fprintf函数打印log,完美解决! #ifdef DEBUG #define NSLog(FORMAT, ...) fprintf(stderr, "%s:%z ...
- 杭电 1002 A + B Problem II【大数相加】
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1002 解题思路:就是把大的数用数组存放起来,像小学的时候用竖式加法来算两个数相加那样算: 反思:思路很 ...