JavaScript 中this的实现原理
学懂 JavaScript 言语,一个标志就是了解下面两种写法,或许有不一样的成果。
<blockquote "="">
var obj = { foo: function () {} }; var foo = obj.foo; // 写法一 obj.foo() // 写法二 foo()
上面代码中,尽管obj.foo和foo指向同一个函数,可是履行成果或许不一样。请看下面的比如。
<blockquote "="">
var obj = { foo: function () { console.log(this.bar) }, bar: 1 }; var foo = obj.foo; var bar = 2; obj.foo() // 1 foo() // 2
这种差异的原因,就在于函数体内部使用了this关键字。许多教科书会通知你,this指的是函数运转时地点的环境。关于obj.foo()来说,foo运转在obj环境,所以this指向obj;关于foo()来说,foo运转在大局环境,所以this指向大局环境。所以,两者的运转成果不一样。
这种解释没错,可是教科书往往不通知你,为什么会这样?也就是说,函数的运转环境到底是怎么决议的?举例来说,为什么obj.foo()就是在obj环境履行,而一旦var foo = obj.foo,foo()就变成在大局环境履行?
本文就来解释 JavaScript 这样处理的原理。了解了这一点,你就会完全了解this的效果。
二、内存的数据结构
JavaScript 言语之所以有this的规划,跟内存里边的数据结构有关系。
<blockquote "="">
var obj = { foo: 5 };
上面的代码将一个目标赋值给变量obj。JavaScript 引擎会先在内存里边,生成一个目标{ foo: 5 },然后把这个目标的内存地址赋值给变量obj。
也就是说,变量obj是一个地址(reference)。后面如果要读取obj.foo,引擎先从obj拿到内存地址,然后再从该地址读出原始的目标,返回它的foo特点。
原始的目标以字典结构保存,每一个特点名都对应一个特点描绘目标。举例来说,上面比如的foo特点,实际上是以下面的方式保存的。
<blockquote "="">
{ foo: { [[value]]: 5 [[writable]]: true [[enumerable]]: true [[configurable]]: true } }
留意,foo特点的值保存在特点描绘目标的value特点里边。
三、函数
这样的结构是很明晰的,问题在于特点的值或许是一个函数。
<blockquote "="">
var obj = { foo: function () {} };
这时,引擎会将函数独自保存在内存中,然后再将函数的地址赋值给foo特点的value特点。
<blockquote "="">
{ foo: { [[value]]: 函数的地址 ... } }
因为函数是一个独自的值,所以它可以在不同的环境(上下文)履行。
<blockquote "="">
var f = function () {}; var obj = { f: f }; // 独自履行 f() // obj 环境履行 obj.f()
四、环境变量
JavaScript 允许在函数体内部,引用当时环境的其他变量。
<blockquote "="">
var f = function () { console.log(x); };
上面代码中,函数体里边使用了变量x。该变量由运转环境提供。
现在问题就来了,因为函数可以在不同的运转环境履行,所以需要有一种机制,http://www.qijihu.com专卖网站可以在函数体内部获得当时的运转环境(context)。所以,this就呈现了,它的规划意图就是在函数体内部,指代函数当时的运转环境。
<blockquote "="">
var f = function () { console.log(this.x); }
上面代码中,函数体里边的this.x就是指当时运转环境的x。
<blockquote "="">
var f = function () { console.log(this.x); } var x = 1; var obj = { f: f, x: 2, }; // 独自履行 f() // 1 // obj 环境履行 obj.f() // 2
上面代码中,函数f在大局环境履行,this.x指向大局环境的x。
在obj环境履行,this.x指向obj.x。
回到本文开头提出的问题,obj.foo()是经过obj找到foo,所以就是在obj环境履行。一旦var foo = obj.foo,变量foo就直接指向函数自身,所以foo()就变成在大局环境履行。
(完)
JavaScript 中this的实现原理的更多相关文章
- JavaScript中实现DI的原理(二)
JavaScript中实现DI的原理 在JavaScript中实现DI,看起来难,实际上原理很简单,它的核心技术是Function对象的toString().我们都知道,对一个函数对象执行toStri ...
- JavaScript中this的工作原理以及注意事项
在JavaScript中,this 的概念比较复杂.除了在面向对象编程中,this 还是随处可用的.这篇文章介绍了this 的工作原理,它会造成什么样的问题以及this 的相关例子. 要根据this ...
- 详解javascript中this的工作原理
在 JavaScript 中 this 常常指向方法调用的对象,但有些时候并不是这样的,本文将详细解读在不同的情况下 this 的指向. 一.指向 window: 在全局中使用 this,它将会指向全 ...
- 【干货理解】理解javascript中实现MVC的原理
理解javascript中的MVC MVC模式是软件工程中一种软件架构模式,一般把软件模式分为三部分,模型(Model)+视图(View)+控制器(Controller); 模型:模型用于封装与应用程 ...
- javaScript中闭包的工作原理
一.什么是闭包? 官方”的解释是:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分.相信很少有人能直接看懂这句话,因为他描述的太学术.其实这句话 ...
- javascript中new操作符的原理
javascript中的new是一个语法糖,对于学过c++,java 和c#等面向对象语言的人来说,以为js里面是有类和对象的区别的,实现上js并没有类,一切皆对象,比java还来的彻底 new的过程 ...
- JavaScript中的作用域链原理
执行环境 作用域链的形成与执行环境(Execution Environment)相关,在JavaScript当中,产生执行环境有如下3中情形: 1 进入全局环境 2 调用eval函数 3 调用func ...
- JavaScript中的原型继承原理
在JavaScript当中,对象A如果要继承对象B的属性和方法,那么只要将对象B放到对象A的原型链上即可.而某个对象的原型链,就是由该对象开始,通过__proto__属性连接起来的一串对象.__pro ...
- JavaScript中的原型链原理
工作中经常解除到prototype的概念,一开始错误的认为prototype是对象的原型链,其实prototype只能算是JavaScript开放出来的原型链接口,真正的原型链概念应该是__proto ...
随机推荐
- webform之Repeater控件
一.Repeater控件 数据循环编辑 1.repeater包括五大模板: (1)HeaderTemplate:标题模板,对开头进行编辑,只执行一次 (2)FooterTemplate:页尾结束模板, ...
- C# 趣味小程序(4)——遍历特定目录及其子目录
//递归方法遍历目录,并统计其中文件的数目 private int statisticFiles(string directory) { int st ...
- NB-IoT移远BC95使用小结
移远-BC95-测试前准备 1. 设备连接主串口,串口调试助手波特率使用9600,选择对应的端口号.在串口调试助手上输入AT发送,查看是否有OK返回. 如果想修改波特可以通过下面的AT来修改 AT+ ...
- Spring cloud(2)B Eureka 注册微服务到服务中心
1.在provide上添加pom(必须加上web) 如果不加 启动后就会自己关闭 <dependency> <groupId>org.springframework.clo ...
- 笨方法学python 22,前期知识点总结
对笨方法学python,前22讲自己的模糊的单词.函数进行梳理总结如下: 单词.函数 含义 print() 打印内容到屏幕 IDLE 是一个纯Python下自带的简洁的集成开发环境 variable ...
- Zabbix笔记
简单检查中的icmppingloss[<target>,<packets>,<interval>,<size>,<timeout>] 结 ...
- numpy.distutils.system_info.NotFoundError: no lapack/blas resources found问题解决
操作环境 Python3.6 + Windows7 问题现象 利用pip自动安装seaborn/numpy/scipy(pip install seaborn)模块失败,提示numpy.distu ...
- Python开发环境搭建指导
本文主要介绍Python开发环境的搭建.主要包括如下几部分内容: (1)Python软件的安装.注意版本的选择和安装过程中选项的勾选. (2)pip工具环境变量.镜像源的配置使用和常用镜像源介绍.pi ...
- linux目录结构详解(以suse linux 10为例)
一.文件系统结构 位于Linux系统的最顶端即根目录是/.Linux的文件系统的入口就是/,所有的目录.文件.设备都在/之下,/就是Linux文件系统的组织者,也是最上级的领导者. 它之下的子目录有: ...
- JAVAWEB 一一 Hibernate(框架)
实体类关联数据库字段,操作实体类,HQL语句对数据结构CRUD) 引入jar包 配置文件 hibernate.cfg.xml User.hbm.xml <?xml version="1 ...