javascript闭包学习

 

Javascript闭包

 

介绍:

 

         闭包:一个闭包是可以在该函数环境中绑定变量和共享变量的表达式(一种特殊的function.闭包是javascript的最强大的特性之一,但是不理解就没法使用。然而,闭包是相对简单编写的,但是编写可能极具潜在的问题,特别是在一些常用的web浏览器。为了避免各浏览器的残缺和利用其优势,就有必要了解其机制了。这很大程度上取决于域链(作用域链)在标识符的解析处理方案和对象的属性名的解析处理方案中扮演的角色。

 

         最简单的闭包就是jsfuncton(体)的内部function:把Function定义和function表达式放入function体中,并且这些内部function是允许访问(function体)所有的局部变量,参数和声明的其他内部函数。

 

         当一个内部function去访问其所在function体之外的function时,闭包就形成了。因此它会在外部的function执行后执行。Function体内的变量,参数都可以被这些内部function所访问和修改,所以这是值得注意的。

 

         不幸的是:正确理解闭包需要理解他们背后的运行机制和一些技术细节。虽然一些ECMA 262的算法已被抛弃,但是不能省略,如果属性的人,可以跳过这部分。

 

 

 

对象的属性解析方案:

 

ECMAScript识别两类对象目录:本地对象和内建对象:就是本地对象的一个子目录。本地对象属于语言,主机对象是环境提供的,也许是,比如:document对象,DOM节点之类的。

 

 

 

本地对象是离散和动态的属性表()。这定义命名成对象的属性将赋予一个值,这可能是一个到其他对象的引用或者一个原始的值:String, Number, Boolean, Null or Undefined。未定义的原始类型可能有点古怪:它可能被undefined值标示,类似于对象的一个属性,它并没有删除任何对象属性。它包含一个undefined命名的属性,它只有值:undefined.

 

 

 

接下来是如何为对象的属性设置值和取值的简述:

 

赋值操作:

 

对象的属性可以被创建,或给已有属性赋值:

 

Var objectRef = new Object();//create a generic javascript object

 

//testNumber属性的创建:

 

objectRef.testNumber = 5;

 

//或者

 

objectRef[“testNumber”] = 5;

 

 

 

对象没有某属性时,会创建属性并赋值。如果有了属性,则只赋值,不需要创建属性了。

 

 

 

Javascript的对象有原型也是对象,也可被简单的描述。原型也许有命名的属性,但是没有被标示。如果这个值被标示,那实际上对象没有一个这名字的属性创建和赋值,如果它有这个属性,就会被重设值。所以:对象的原型是不能为对象创建属性并赋值的。

 

 

 

读取属性值:

 

从对象来读取属性值是由对象原型来完成的。如果对象有个命名的属性,那么用属性运算符就额可以访问该属性,并返回属性值:

 

objectRef.testNumber = 8;

 

//read the value back from the property

 

Var val = objectRef.testNumber;

 

 

 

但是所有的对象都有原型,并且原型也是对象,反过来,也许有原型,也有其原型等等就会造成所谓的原型链(prototype chain)。原型链终结于原型链中的某个对象是空原型。Object对象的默认的原型就有个null原型。

 

var objectRef = new Object();//create a generic js object

 

 

 

Object的原型创建一个对象:对象就有了一个null原型。因此,objectRef的原型链只有一个对象:Object.prototype.然而:

 

 

 

<script type="text/javascript">

 

function MyObject1(formalParameter){

 

         this.testNumber = formalParameter;

 

}

 

function MyObject2(formalParameter){

 

         this.testString = formalParameter;

 

}

 

MyObject2.prototype = new MyObject1( 8 );

var objectRef = new MyObject2( "String_Value" );

</script>

 

MyObject2实例提供了objectRef变量的原型链。原型链的第一个对象是:MyObject1实例(已被创建和标示为MyObject2对象的原型)。MyObject1有一个原型,这个对象被标示为MyObject1的原型属性。这个对象也有原型,就是Object对象默认的原型,可以通过Object.prototype的简称来通信。Object.prototype有个null原型,因此这个原型链在这个点终结。

 

当尝试去访问一个命名的属性时,整个原型链会参与到访问过程。如:

 

var val = objectRef.testString;//String_Value

 

实例MyObject2objectRef提供一个属性:“testString,因此就是这个属性的值,设为”String_Value”,也被标示为值。然而:

 

原型链(prototype chain

 

objectRef.prototype-> (MyObject2.prototype) -> MyObject1.prototype->Object.prototype

 

Var val = objectRef.testNumber;

 

不能从MyObject2实例读取这个名字的属性。因为他没有这样的属性。而MyObject2的原型:MyObject1实例已被创建并创建属性:testNumber,并且赋值8;因此属性运算符返回值8.

 

还有MyObject1MyObject2都没有一个toString()方法,如果尝试从objectRef去访问去获取值:

 

var val = objectRef.toString;

 

那么val变量被标示为一个function的引用。这个functionObject.prototype的一个属性并且返回值。

 

最后:

 

var val = objectRef.madeUpProperty;

如果这么做,遍历了所有的原型都没有找到这个属性或者方法,那么就返回undefined了。

 

读属性值会返回第一个找到的值,在对象找或者原型链。对象的属性在被赋值时,如果没有该属性就赋值,否则会创建。原型链类似于java 的类基础。

 

 

每个对象都有自己的原型链,返回自己的原型链的值。如果通过原型链去找属性值,那么返回的是就近的属性值。

 

 

标识符解析,执行上下文和作用域链

 

执行上下文:是个抽血概念,用于ECMA 262的定义来描述ECMA要求的实现方式。这个定义没有说任何关于执行上下文是如何实现的,但是执行上下文有关联属性来提供定义结构,因此他们可能被接受为objects和属性,虽然没有公共属性。

 

所有的js代码被执行在一个执行上下文,全局代码开始执行是在全局执行上下文,并且每个函数调用都有一个相关联的执行上下文Eval函数的执行会获取不同的执行上下文,Eval函数从来不被常规的使用在js编程中,所以也不在这里讨论了。执行上下文的细节会在ECMA 26210.2节找到。

 

 

 

当一个js函数被调用,js函数就进入了一个执行上下文,如果另一个函数也被调用了,那么一个新的执行上下文会被创建并在这个函数调用期间。当执行结束后,返回原来的执行上下文。所以,js代码的执行形式是一个栈结构。后进先出。

 

当执行上下文创建了很多东西时,首先,在上下文函数中,Activation”对象被创建,这个对象是另一个规范机制。可以视为一个对象,但是它没有属性,也不能在js代码里直接引用这个对象。

 

下一步就是创建一个 arguments 对象,长得像一个数组有整形索引来快速的返回参数,为了序列,它又长度和callee的属性。激活对象的属性被创建并命名为:“arguments”并且提供到每一个对象。

 

下一步:执行上下文标示一个域:一个包含了很多对象的list,每个对象都有范围内的属性,也包含了一系列的对象。范围是分配给执行上下文的一个函数调用由列表中所提到的【[范围] ]属性对应的函数对象的激活对象添加在前面的链(或列表的顶部)。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值