js作用域

来源:互联网 发布:如果女朋友是病娇 知乎 编辑:程序博客网 时间:2024/06/05 11:58

深入理解javaScript作用域

1.介绍
JavaScript有一个称为作用域的功能。 虽然作用域的概念对于许多开发新人来说并不容易理解,但我将尽力向您解释最简单作用域。了解作用域将使您的代码脱颖而出,减少错误并帮助您制作强大的设计模式。
2.什么是作用域?
作用域是代码运行时某些特定部分的变量,函数和对象的可访问性。 换句话说,作用域决定了代码区域中变量和其他资源的可见性。
3.为什么作用域?最低访问原则
那么,限制变量的可视性而不是在你的代码随处可见是什么意思?其中一个优点是该作用域为您的代码提供了一定程度的安全性。计算机安全的一个常见原则是,用户一次只能访问他们需要的东西。

深入理解闭包:

1、作用域:js确定作用域是在词法分析阶段通过遍历活动对象来确定的。
更准确的应该是词法作用域。
2、作用域链:在函数定义的阶段被创建的。每个函数都有自己的作用域链,在函数执行的时候被推入一个新的对象用于词法分析。
3、执行环境: 执行环境定义了变量或函数有权访问的其他数据。
4、活动对象:

在函数执行并且返回结果之后,垃圾回收机制会将函数对应的活动对象删除,那么在函数外部不能访问函数内部的变量。(原因:1:在函数外面访问变量时,是通过查找作用域链上的活动对象来实现的,这个作用域链和函数的作用域链没有交集。2:函数的作用域链上包含的活动对象,在函数执行完就被删除了)
查找规则,定义一个变量时,会在当前作用域查找,如果没有这个变量则创建一个;
js预处理(词法分析)阶段实现,在全局环境中运行一段代码时,解释器会创建一个全局作用域,全局作用域会包含列表,也就是作用域链,作用域链上包含了一个对象,也就是活动对象;解释器会通过词法分析对代码进行预处理(逐行扫描),如果碰到了声明语句,首先看当前的活动对象内部是否有声明的变量,如果没有就创建属性,赋值为undefined;预处理后就生成可执行代码->执行代码;
当代码执行时,如果为变量a赋值,解释器会根据作用域链先去查找活动对象,看活动对象内部是否存在属性a,如果存在就为a赋值,如果没有则创建并赋值。同样运行一个函数b时,看活动对象内部是否含有函数b,如果没有则创建赋值为undefined,并运行(此时会报错,b is not a function)。
当对变量进行赋值时,解释器会在作用域链中查看第一项,也就是当前活动对象,如果有则赋值,如果没有则会查看作用域中的第二项,即外部函数的活动对象,…,直至全局活动对象,如果没有,则会在全局作用域创建变量并赋值。
那么使用var和不适用var的区别就是:使用var,在词法分析阶段会把对应的变量放到函数对应的活动对象中,如果不使用var,会跳过词法分析阶段,直接进入到函数执行阶段,因为解释器会沿着作用域链查找变量,如果找到作用域链最后一个(全局作用域)没有找到变量,则会在全局活动对象内创建变量。

闭包:全局环境 包含a b

function a(){}function b(){    a = function c(){       return;    }}

a和c之间有个引用关系,是在执行阶段被创建的。
运行a时,实际就是运行c,c的作用域链上会被推入一个新的活动对象。c(新创建的,用词法分析将c中的代码初始化一边) b 全局。
c中的代码操作某个变量时,会依次查找这三个对象,如果说变量是在b中定义的,就会在b的活动对象中找到并且进行操作,操作的结果也会保存在b的活动对象中国。
函数a运行完成之后,或者说函数a对应的函数c运行完成之后,c自己的活动对象被删除,c的作用域链上还是包含两个活动对象,b 的活动对象和全局活动对象。如果想要删除b的活动对象,就要断开a和c的联系,并且把a赋值为null。在下一次垃圾回收机制运行的时候b的活动对象就被删除了。

JS作用域

1.对于一门变成语言来说最基本的功能是存储。
2.值之间按照一定规则进行保存,在对值进行操作是,也是要先进行读取。
3.值保存和读取的规则,就叫做作用域。(如果范围是以函数为单位就是函数作用域)。
4.作用域可以相互嵌套,但是不可能重叠。

5.js也是一门编译语言

(1)词法,语法分析过程
词法分析:就是将字符流转换为记号流,
例如: var result = testNum1 - testNum2;
词法分析后:

(2)代码生成

为什么eval()和with会导致效率低下?
eval和with会破坏js解释器内部的优化规则,js解释器碰到eval和with后就会按照eval和with内的代码执行。

操作系统提供给应用的接口(内核) (linux C语言=》汇编)
(1)开辟一个进程 (2)杀掉一个进程
(3)申请内存空间 (4)读写内存,释放内存

语言调用C语言接口申请内存空间。有可能申请很大一段,然后自己分配每块存什么。
内存管理: 垃圾回收机制。
java 也有垃圾回收,但是c,c++没有垃圾回收(自己释放掉内存)。

js中的垃圾回收机制:

  1. 原理:找出那些不再使用的变量,然后释放掉其占用的内存。为此,垃圾收集器会按照固定时间间隔,周期性的执行这一操作。
    【变量及变量之间的引用构成一张有向图(有可能有环)。没有用的变量是:从根节点开始搜索,搜索不能到的点,就是需要回收的变量。】
  2. 实现方法:(1)标记清除; (2)引用计数。
    (1)标记清除:垃圾收集器运行的时候会给存储在内存中的==所有变量==加上标记。然后,它会去掉环境中的变量及被环境中的变量引用的变量的标记。而在此后再被加上标记的变量将被视为准备删除的变量,原因是环境中的额变量已经无法访问到这些变量了。
    (2)引用计数(不太常见)跟踪记录每个值的被引用次数。
  3. 内存泄漏:不能被垃圾回收机制回收的但是又不被使用的变量。
原创粉丝点击