以图明志

JavaScript

JavaScript闭包其三:闭包的用法

闭包可以创建出非常优雅的设计
实际使用的时候,闭包可以创建出非常优雅的设计,允许对funarg上定义的多种计算方式进行定制。顺便提下,函数对象的 apply 和 call方法,在函数式编程中也可以用作应用函数。 这里,我们将它们看作是应用函数 —— 应用到参数中的函数(在apply中是参数列表,在call中是独立的参数)……

JavaScript

JavaScript闭包其二:闭包的实现

ECMAScript只使用静态(词法)作用域
讨论完理论部分,接下来让我们来介绍下ECMAScript中闭包究竟是如何实现的。这里还是有必要再次强调下:ECMAScript只使用静态(词法)作用域(而诸如Perl这样的语言,既可以使用静态作用域也可以使用动态作用域进行变量声明)。

JavaScript

JavaScript闭包其一:闭包概论

函数式编程中一些基本定义
前面介绍了作用域链和变量对象,现在再讲闭包就容易理解了。闭包其实大家都已经谈烂了。尽管如此,这里还是要试着从理论角度来讨论下闭包,看看ECMAScript中的闭包内部究竟是如何工作的。众所周知,在函数式语言中(ECMAScript也支持这种风格),函数即是数据。

JavaScript

JavaScript作用域链其三:作用域链特征

作用域链相关的一些重要特征
让我们看看与作用域链和函数[[scope]]属性相关的一些重要特征。在ECMAScript中,闭包与函数的[[scope]]直接相关,正如我们提到的那样,[[scope]]在函数创建时被存储,与函数共存亡。实际上,闭包是函数代码和其[[scope]]的结合。因此,作为其对象之一,[[Scope]]包括在函数内创建的词法作用域(父变量对象)。

JavaScript

JavaScript作用域链其二:函数的生命周期

分为创建和激活阶段
函数的的生命周期分为创建和激活阶段(调用时),让我们详细研究它。众所周知,在进入上下文时函数声明放到变量/活动(VO/AO)对象中。让我们看看在全局上下文中的变量和函数声明(这里变量对象是全局对象自身,我们还记得,是吧?)

JavaScript

JavaScript作用域链其一:作用域链定义

内部上下文所有变量对象的列表
一个执行上下文 的数据(变量、函数声明和函数的形参)作为属性存储在变量对象中。变量对象在每次进入上下文时创建,并填入初始值,值的更新出现在代码执行阶段。这一章专门讨论与执行上下文直接相关的更多细节,这次我们将提及一个议题——作用域链。如果要简要的描述并展示其重点,那么作用域链大多数与内部函数相关。

JavaScript

JavaScript变量对象其五:__parent__ 属性

通过这个属性可以直接引用到活动对象
前面已经提到过,按标准规范,活动对象是不可能被直接访问到的。但是,一些具体实现并没有完全遵守这个规定,例如SpiderMonkey和Rhino;的实现中,函数有一个特殊的属性 __parent__,通过这个属性可以直接引用到活动对象(或全局变量对象),在此对象里创建了函数。

JavaScript

JavaScript变量对象其四:关于变量

变量只能通过使用var关键字才能声明
通常,各类文章和JavaScript相关的书籍都声称:“不管是使用var关键字(在全局上下文)还是不使用var关键字(在任何地方),都可以声明一个变量”。请记住,这是错误的概念:任何时候,变量只能通过使用var关键字才能声明。“不是变量”并不是说它不能被改变,而是指它不符合ECMAScript规范中的变量概念。

JavaScript

JavaScript变量对象其三:执行上下文的两个阶段

执行上下文代码分成两个阶段来处理
现在我们终于到了本文的核心点了。执行上下文的代码被分成两个基本的阶段来处理:进入执行上下文与执行代码。变量对象的修改变化与这两个阶段紧密相关。这2个阶段的处理是一般行为,和上下文的类型无关(也就是说,在全局上下文和函数上下文中的表现是一样的)。

JavaScript

JavaScript变量对象其二:VO在不同的执行上下文中

不同执行上下文中的变量对象
对于所有类型的执行上下文来说,变量对象的一些操作(如变量初始化)和行为都是共通的。从这个角度来看,把变量对象作为抽象的基本事物来理解更为容易。同样在函数上下文中也定义和变量对象相关的额外内容。当访问全局对象的属性时通常会忽略掉前缀,这是因为全局对象是不能通过名称直接访问的。

JavaScript

JavaScript变量对象其一:VO的声明

一个与执行上下文相关的特殊对象
如果变量与执行上下文相关,那变量自己应该知道它的数据存储在哪里,并且知道如何访问。这种机制称为变量对象(variable object)。变量对象(缩写为VO)是一个与执行上下文相关的特殊对象,它存储着在上下文中声明的以下内容:变量 (var, 变量声明);函数声明 (FunctionDeclaration, 缩写为FD);函数的形参。

JavaScript

JavaScript函数其四:函数构造器

这种函数的[[Scope]]属性仅包含全局对象
既然这种函数对象也有自己的特色,我们将它与FD和FE区分开来。其主要特点在于这种函数的[[Scope]]属性仅包含全局对象。我们看到,函数bar的[[Scope]]属性不包含foo上下文的Ao——变量”y”不能访问,变量”x”从全局对象中取得。

JavaScript

JavaScript函数其三:分组中的函数表达式

函数创建后的调用中用圆括号来包住它
让我们回头并回答在文章开头提到的问题——”为何在函数创建后的立即调用中必须用圆括号来包围它?”,答案就是:表达式句子的限制就是这样的。按照标准,表达式语句不能以一个大括号{开始是因为他很难与代码块区分,同样,他也不能以函数关键字开始,因为很难与函数声明进行区分。

JavaScript

JavaScript函数其二:函数表达式

它在源码中总是处在表达式的位置
另外一种可以取代函数声明的方式是函数表达式,解释如下:在源码中须出现在表达式的位置,有可选的名称,不会影响变量对象,在代码执行阶段创建。这种函数类型的主要特点在于它在源码中总是处在表达式的位置。

JavaScript

JavaScript函数其一:函数声明

主要特点在于它们仅仅影响变量对象
下面我们介绍的是一个非常常见的ECMAScript对象——函数(function),我们将详细讲解一下各种类型的函数是如何影响上下文的变量对象以及每个函数的作用域链都包含什么,以及回答诸如像下面这样的问题:下面声明的函数有什么区别么?(如果有,区别是什么)。

JavaScript

JavaScript探秘:强大的原型和原型链

JavaScript继承模型使用 prototypal 原型模型
JavaScript 不包含传统的类继承模型,而是使用 prototypal 原型模型。虽然这经常被当作是 JavaScript 的缺点被提及,其实基于原型的继承模型比传统的类继承还要强大。实现传统的类继承模型是很简单,但是实现 JavaScript 中的原型继承则要困难的多。
1 / 3 首页 < Prev 1 2 3 Next > 尾页 页码: