L1 - 闭包和原型链

  先来一炮尝尝:

var i = 10;

function myFunc(){

    var i = 20;
    function innerFunc(){
        alert(i);
    }

    return innerFunc;
}

var func = myFunc();

func();

  此栗为什么弹出20,而不是10?为什么定义在 myFunc 内部的 innerFunc 返回了以后,还能访问到 myFunc 内部的变量 i ?

  这是因为在 innerFunc 返回了以后,仍然保留着函数运行的实例、执行环境和作用域链等等,并在 myFunc 调用之后没有将函数实例丢弃,因此在调用 innerfunc 的时候能够引用到 myfunc 中声明的 i ,这就是闭包的特性,其实上面的栗子就是一个闭包。

  作用域链是一个链状的数据结构。作用域就是对上下文数据的描述。闭包和作用域链是紧密联系的,函数实例执行时的闭包是构成作用域链的基本元素。javascript代码在执行前会进行语法分析(详见L1 - 运行机制),在语法分析阶段,会记录全局环境中的变量声明和函数定义,构造函数的调用对象(也叫 active object、活动对象)和在全局环境下的作用域链。

  《javascript权威指南》(第四版)对“调用对象”做出了三点说明:

  1、对象属性和变量没有本质区别

  2、全局变量其实是“全局对象(global object)“的属性

  3、局部变量其实是”调用对象(call object)“的属性

  为了解释上述话题,《javascript权威指南》引入了”javascript执行环境(执行上下文、execution context)的概念“。这其中所说到的“全局对象(global object)“和”调用对象(call object)“其实都是指下图中的 ScriptObject 结构。

  上图是《JavaScript语言精髓和编程实践》中对闭包相关元素的内部数据结构的描述,其中的 ScriptObject 是对调用对象的一种描述。 ScriptObject 在语法分析阶段就已经构造好了,其中的 varDecls 保存着函数中的变量声明,funDecls保存着内部的函数声明。

  在上篇《执行机制》中已经讲过,在语法分析阶段,varDecls 中保存着在函数中用var进行显示声明的局部变量,并且其值默认为 undefined ;而发现有函数定义时,除了记录函数声明,还会创建一个函数对象,并把当前的作用域链赋值给此函数对象的 [[scope]] 属性(这个属性是javascript引擎内部维护的,但Firefox可通过私有属性parent访问它)。这就是为什么在《javascript权威指南》中提到”javascript中的函数运行在它们被定义的作用域中,而不是运行在它们被执行的作用域中“。

  再来一炮:(未完待续)

时间: 2024-08-25 06:14:38

L1 - 闭包和原型链的相关文章

闭包,原型链

闭包 在[函数定义]的时候,[函数对象]的[scope属性]便会引用包含该函数的上一级函数在运行时所生成的[执行上下文]的[活动对象],因为发生对象属性之间的相互依赖,导致包含此函数的[scope属性]所指向的活动变量,在上一级函数[执行完毕]将要[释放执行上下文]的时候[不能释放]其包含的[活动变量]. 自己的理解: 闭包的产生首先要有一个地址被引用所指向 函数与对象的关系 函数就是对象的一种 对象是函数创建的 prototype原型 prototype是函数的一个属性 每一个构造函数都有pr

作用域链、闭包和原型链

Function:  匿名函数,作用域,作用域链和闭包 函数的重载:  什么是:函数名相同,参数列表不同.根据传入函数的参数的不同,整形不同的逻辑. 何时用:如果一项任务,根据不同的参数,不执行不用的逻辑. 优点:减轻调用者的负担.  问题:js语法不知函数的重载. 解决办法:在函数中都有arguments的属性,专门用于接收传入函数的所有参数值的类数组对象. 匿名函数:  什么是:在函数定义时,不给函数名,即不被任何变量引用. 何时用:确定函数只使用一次.  优点:节约内存. 如何用:1.自调

闭包和原型链

闭包: 简单的理解就是:闭包就是能够读取其他函数内部变量的函数,它两个最大的用处:①可以读取函数内部的变量,②让变量的值始终保持在内存中.闭包与它的词法环境绑在一起,因此闭包让我们能够从一个函数内部访问其外部函数的作用域 . 原型链: 对象之间的继承关系,在JavaScript中是通过prototype对象指向父类对象,直到指向Object对象为止,这样就形成了一个原型指向的 链条,称之为原型链. 原文地址:https://www.cnblogs.com/JankinLiu/p/10347293

原型、原型链、闭包、继承

一.原型.原型链 原型对象    在JavaScript 中,每当定义一个对象(函数)时候,对象中都会包含一些预定义的属性.其中函数对象的一个属性就是原型对象 prototype.注:普通对象没有prototype,但有__proto__属性. 原型对象其实就是普通对象(Function.prototype除外,它是函数对象,但它很特殊,他没有prototype属性(前面说道函数对象都有prototype属性)).看下面的例子:  function f1(){};  console.log(f1

1、AJAX里面status的值代表什么 2、get post 的区别 3、怎样把对象转化成字符串 4、闭包、继承、原型、原型链 5 、http传输协议 6、arguments是什么

1.AJAX里面status的值代表什么     在JavaScript里面写AJax的时,最关键的一步是对XMLHttpRequest对象建立监听,即使用"onreadystatechange"方法.监听的时候,要对XMLHttpRequest对象的请求状态进行判断,通常是判断readyState的值为4且status的值为200或者304时执行我们需要的操作.以下记录了一些常用readState以及status的值及其含义 readyState 属性表示Ajax请求的当前状态.它的

JavaScript概念总结:作用域、闭包、对象与原型链

1 JavaScript变量作用域 1.1 函数作用域 没有块作用域:即作用域不是以{}包围的,其作用域完成由函数来决定,因而if /for等语句中的花括号不是独立的作用域. 如前述,JS的在函数中定义的局部变量只对这个函数内部可见,称之谓函数作用域. 嵌套作用域变量搜索规则:当在函数中引用一个变量时,JS会搜索当前函数作用域,如果没有找到则搜索其上层作用域,一直到全局作用域. [javascript] view plain copy print? var  value = 'global';

作用域、原型链、闭包等概念理解

1.执行环境及作用域 (1).执行环境: 定义了变量或函数有权访问的其它数据,决定了它们的各自行为.每个执行环境都有一个与之关联的变量对象(variable object, VO),执行环境中定义的所有变量和函数都会保存在这个对象中,解析器在处理数据的时候就会访问这个内部对象. 全局执行环境是最外层的一个执行环境,在web浏览器中全局执行环境是window对象,因此所有全局变量和函数都是作为window对象的属性和方法创建的.每个函数都有自己的执行环境,当执行流进入一个函数的时候,函数的环境会被

Javascript-我对作用链、闭包、原型及原型链的理解

Javascript-基础概念总结(2) 最近学习一些javascript基础知识,也解决了很多之前的疑惑,记得第一次被问及怎样理解闭包时,我的回答是:就是类似于封装吧!现在想想是有多白痴,学习技术是需要逻辑性很强的,技术注重用事实和数据说话,每一点都需要理解透彻,在技术上没有猜测,没有套路,以后自己在回答技术性的问题时,应做到知道就是知道,不理解或不太明白的,就诚实对待,这样有助于自己积累知识,了解自己的不足,从而提升自己.讲了那么多题外话,是为了让自己认识到应真诚的对待学习.下面是一些我的知

标识符解析、作用域链、运行期上下文、原型链、闭包

本文讲到的是如何从数据访问层面上提高JS 代码的执行效率.总的来讲有以下几条原则: 函数中读写局部变量总是最快的,而全局变量的读取则是最慢的: 尽可能地少用with 语句,因为它会增加with 语句以外的数据的访问代价: 闭包尽管强大,但不可滥用,否则会影响到执行速度以及内存: 嵌套的对象成员会明显影响性能,尽量少用: 避免多次访问对象成员或函数中的全局变量,尽量将它们赋值给局部变量以缓存. 这么几句话看似简单,但要深刻理解其中的道理则需涉及到JS的 标识符解析.作用域链.运行期上下文(又称为执