这是我学习JavaScript的第二篇文章,之前做过几年的Java开发,发现JavaScript虽然也是面向对象的语言但是确实有很多不同之处。就本篇博客,主要学习总结一下最近学习到的JavaScript的知识,其中有些是网络上的,不过对于理解JavaScript,和在工作总是会很实用的,所以总结了下来:

那么就开始吧,首先是变量

在JavaScript中变量分为两种:一种是基本类型,基本类型值在内存中占用固定大小的空间,因此被保存在栈内存中。从一个变量向另一个变量复制基本类型的值,会创建这个值的一个副本。另一种类型则是引用类型,引用类型的值是对象,保存在堆内存中,对象的引用保存在栈中。包含引用类型值的变量实际上包含的并不是对象本身,而是一个指向对象的指针,从一个变量向另一个变量复制引用类型的值,复制的是指针,最终指向同一个对象。

那么在实际的使用中要确定一个值是那种基本类型的可以使用typeof操作符,而确定一个值是哪种引用类型则需要使用instanceof 操作符。

基本数据类型:undefined、Null、boolean、number和String

引用类型:Object、Array、Date、RegExp、Function、基本包装类型、单体内置对象(Gloabal、Math)。关于引用类型各个类型的详细使用,下次再详细描述。

JavaScript是面向对象的语言,同样支持继承,只是JavaScript支持实现继承,不支持接口继承。

JavaScript是一种非强类型的语言,不需要严格的如同Java、C等语言的声明类型然后复制,也一定要赋值声明类型的值。JavaScript有两种值类型,所以涉及到两个地方复制,一种就是复制变量值,另一个则是方法调用的时候存在参数传递赋值。基本类型是值复制,引用类型复制是对象的引用。

作用域

js中没有块作用域的概念。在没有var进行声明则会生成为全局变量污染全局环境。所以在实际的使用过程中,一定要记得var,js对变量的搜索是一层一层往上搜索,如果搜索到变量则停止往上搜索(所以搜索变量的层次越多肯定会小小的影响程序性能)。

延长作用域链

虽然执行环境的类型总共只有两种--全局和局部(函数),但还是有其他办法来延长作用域链。这是因为有些语句可以在作用域链的前端临时增加一个变量对象,该变量对象会在代码执行后被移除。那么具体是哪写情况呢?具体就两种:

(1)、try-catch 语句的catch块。

(2)、with语句块。

这两个语句都会在作用域链的前端添加一个变量对象。对with语句来说会指定对象添加到作用域链中。对catch语句来说,会创建一个新的变量对象,其中包含的是被抛出的对象的声明。所以在try-catch 和with要慎用,with是不推荐使用的。在严格模式下,是不能使用,但是我们要对with有一些了解。用一个例子解说:

with(location){
var qs=search.substring(1);
var hostname=hostname;
var url=href;
}

 href 和hostname 都是location.hostname 和location.url

好了,稍后来说一下JS的执行环境,js的执行环境是很复杂的,我肯定也是不能全部说清楚的,下面就根据我所了解的简单总结了几个重点,后期了解到更多后,在加入到本次的博客中。

执行环境和全局执行环境、异步执行机制、事件和回调函数、Event Loop、定时器、Js垃圾收集 这六个方面。

1、执行环境和全局执行环境

执行环境有全局执行环境(也称为全局环境)和函数执行环境之分。

每次进入一个新环境,都会创建一个用于搜索变量和函数的作用域链,这些搜索向前面说的一样,是一层一层向上搜索的。

函数的的局部环境不仅有权访问函数作用域中的变量,而且有权访问其包含(父)环境,乃至全局环境。

有全局环境只能访问在全局环境中定义的变量和函数,而不能直接访问局部环境中的任何数据。变量的执行环境有助于确定应该何时释放内存。

2、异步执行机制

JavaScript是单线程的,也就是说同一个时间只能做一件事情。那么所有的任务需要排队执行,如果某一个任务执行很慢,则会影响整个性能,那么JavaScript又是怎么处理的呢?

JavaScript中的任务分为两种:一种是同步任务,另一种是异步任务;也就是synchronous 和asynchronous 两种任务。同步任务指的是在主线程上排队执行的任务。异步任务指的是,不进入主线程,而进入任务队列(task queue)的任务,只有“任务队列” 通知主线程,某个异步任务可执行了,该任务才会进入主线程执行。

异步执行的允许机制如下:

(1)、所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。

(2)、在主线程队列之外,还存在一个任务队列。只要异步任务有了运行结果,就在任务队列中放置一个事件。

(3)、一旦“执行栈”中的所有同步任务执行完成,系统就会查询“任务队列”,有哪些事件,哪些对应的异步任务,于是结束等待状态,进入执行栈。开始执行。

(4)、主线程不断重复上面的(3)。

只要主线程空了,就会读取“任务队列”。

3、事件和回调函数

“任务队列”是一个事件的队列,IO设备、鼠标点击、页面滚动等等,完成一项任务,就在“任务队列”中添加一个事件,表示相关的异步任务可以进入“执行栈”。也就是主线程执行的队列中。主线程执行。

所谓“回调函数”(callback),就是哪些会被主线程挂起来的代码。异步任务必须指定回调函数,当主线程开始执行异步任务,就是执行对应的callback函数。

“任务队列”,要等到主线程将主线程中的执行队列执行完之后,就进入执行任务队列。但是,由于存在后文提到的“定时器”功能,主线程首先要检查一下执行时间,某些时间只有到了规定的时间,才能返回主线程。

4、Event Loop

主线程从“任务队列”中读取事件,这个过程是不断循环,所以整个的这种运行机制称为Event Loop。一个进程只能执行一个任务要能执行多个任务,需要下面三种方法:

(1)、排队。因为一个进程一次只能执行一个任务,只好等当前的任务执行完了,再执行后面的任务。

(2)、新建进程。使用fork新建一个进程。

(3)、新建线程。因为进程太耗费资源,可以使用进程进行多任务执行。

JavaScript则是排队的方式处理的,但是存在一个始终运行的Event loop来进行监控哪些事件需要触发,如果需要触发,则通知主线程执行回调函数。也就是上面描述2、异步执行机制中的 (3)、(4)中的(3)。这样主线程在任务多的时候达到任务饱和。不像多线程中那样存在多个线程的上下文和执行环境的切换的消耗。

5、定时器

了解了上面的事件回调合 任务队列,那么定时器这个异步任务事件,就能很好的理解啦,即指定某些代码在多少时间之后执行。这叫“定时器”功能,也就是定时执行的代码。定时器功能有setTimeout()和setInterval()这两个函数来完成,它们的内部运行机制完全一样,区别是前者指定的代码是一次执行,后者反复执行。setTimeout()的第二个参数为0,就表示当前主线程任务清空后。立即执行指定的回调函数。 这种方式可以将耗时的方法,setTimeout到任务队列中,任务队列中存在先后顺序。

6、Js垃圾回收

上面说到执行环境有助于垃圾回收,是什么意思呢?就是离开作用域的值将被自动标记为可以回收,因此将在垃圾收集期间被删除。

现在垃圾收集比较常用的都是“标记删除”,这种算法的思想是给当前不使用的值加上标记,然后再回收其内存。

还有一种“引用计数算法”,这种算法的思想是跟踪记录所有值被引用的次数。之前IE在使用,但是现在JavaScript不再使用这种算法,因为可能会出现内存泄漏的问题,具体为什么,如果代码中存在循环引用现象,将会导致泄漏。垃圾收集器是周期性运行的,而且如果为变量分配的内存数量很乐观,那么回收的工作量也是相当大的。如果需要清理的空间大。这种情况下,确定垃圾收集的事件间隔是一个非常重要的问题,存在垃圾收集机制的语言编写代码比较方便,但是内部的机制也相对比较复杂,确保占用的内存少可以让页面得到好更好的性能。而优化内存占用的最佳方式,就是为执行中的代码只保存必要的数据。一旦数据不不再有用,最后通过将其设置为null来释放引用 这种做法叫做解除引用。这一做法适用于大多数全局变量和全局变量的熟悉。局部变量会在它们离开执行环境的时候自动解除引用。解除一个值的引用并不意味着自动回收该值占用的内存,而是表示该空间可以回收。解除引用的真正的目的也是让值脱离执行环境,以便垃圾收集器下次回收其空间。

关于JavaScipt的运行机制我总结的肯定不一定准确全面,希望在今后的工作和学习中,更加了解,这样才能知其然,并知其所以然。

参考资料

《JavaScript高级程序设计》

http://www.ruanyifeng.com/blog/2014/10/event-loop.html

JavaScript 中变量、作用域和内存问题的学习的更多相关文章

  1. 浅谈javascript中变量作用域和内存(2)

    1.无块级作用域 javascript没有块级作用域,这会让其他程序员在理解js代码上很痛苦.在其他很多语言,比如C,大括号括起来的代码块都有自己的作用域 举个例子 if(true) { var na ...

  2. 浅谈javascript中变量作用域和内存(1)

    先理解两个概念:基本类型和引用类型的值 1.基本类型和引用类型的值 (1)定义: 基本类型:指简单的数据段,比如按值访问的js五种基本数据类型undefined.null.boolean.number ...

  3. Javascript中变量作用域(2)

    多层函数调用取变量时,无论在哪里调用,要到创建此函数的作用域中取值,如果找不到再往上一级,直到全局变量. 外面定义了很多的全局的变量,下面我们来一个个理一下. 定义三个变量a,b,c;将A1函数赋值给 ...

  4. Javascript中变量作用域

    <script type="text/javascript"> var a = 10; var Bar = (function () { console.log(a); ...

  5. 第一百零六节,JavaScript变量作用域及内存

    JavaScript变量作用域及内存 学习要点: 1.变量及作用域 2.内存问题 JavaScript的变量与其他语言的变量有很大区别.JavaScript变量是松散型的(不强制类型)本质,决定了它只 ...

  6. javascript的变量作用域--对比js、php和c的for循环

    为什么要写这篇文章呢?主要是给自己提个醒,js的水很深,需要小心点儿才能趟过去,更何况自己不是专业人士,那就得更加小心了. 看下面的js代码: <!DOCTYPE html> <ht ...

  7. [转]深入理解JavaScript的变量作用域

    1.JavaScript的作用域链 2.函数体内部,局部变量的优先级比同名的全局变量高. 3.JavaScript没有块级作用域. 4.函数中声明的变量在整个函数中都有定义. 5.未使用var关键字定 ...

  8. JavaScript中的作用域

    很多(JavaScript)开发者都在讨论"作用域",但它是什么?它们在JavaScript中的任何地方!我发现很多年轻的开发者不知道作用域是什么.他们中大多数人可以用jQuery ...

  9. 深入理解JavaScript的变量作用域(转载Rain Man之作)

    在学习JavaScript的变量作用域之前,我们应当明确几点: JavaScript的变量作用域是基于其特有的作用域链的. JavaScript没有块级作用域. 函数中声明的变量在整个函数中都有定义. ...

随机推荐

  1. 15个最好的PDF转word的在线转换器,将PDF文件转换成doc文件

    PDF是一种文件格式,包含文本,图像,数据等,这是独立于操作系统的文件类型.它是一个开放的标准,压缩,另一方面DOC文件和矢量图形是由微软文字处理文件.该文件格式将纯文本格式转换为格式化文档.它支持几 ...

  2. Spectrum to XYZ to sRGB

    如何将频谱响应转换为对应的RGB显示值: 首先要在频率功率分布(SPD)曲线的基础上,分别使用X/Y/Z三个频率匹配曲线(spectral matching curves,又名CIE XYZ Colo ...

  3. Swift中对C语言接口缓存的使用以及数组、字符串转为指针类型的方法

    由于Swift编程语言属于上层编程语言,而Swift中由于为了低层的高性能计算接口,所以往往需要C语言中的指针类型,由此,在Swift编程语言刚诞生的时候就有了UnsafePointer与Unsafe ...

  4. 小试ijkplayer编译

    同步发表于 http://avenwu.net/ijkplayer/2015/05/07/hands_on_ijkplayer_preparation 谈到视频播放大家都知道ffmpeg,基于其的衍生 ...

  5. 关于meta知多少

    本来打算写关于手机端的知识,想了想先从meta着手.接下来请大家看几个网站的例子. 一.天猫(http://m.tmall.com) <title>天猫触屏版</title> ...

  6. ASP.NET 回调技术(CallBack)

    在asp.net中客户端与服务器端的交互默认都是整页面提交, 此时客户端将当前页面表单中的数据(包括一些自动生成的隐藏域)都提交到服务器端,服务器重新实例化一个当前页面类的实例响应这个请求,然后将整个 ...

  7. Flash播放mp4的两个问题:编码问题和需要下载完后才能播放的问题

    (1)编码问题.需要是 h.264 编码,不是此编码的在某些Flash版本或OS上会出现放不出来视频的问题:可以用 3GP.MP4视频转换精灵(BRVideoConverter) 转码. (2)下载完 ...

  8. Windows内核安全与驱动开发

    这篇是计算机中Windows Mobile/Symbian类的优质预售推荐<Windows内核安全与驱动开发>. 编辑推荐 本书适合计算机安全软件从业人员.计算机相关专业院校学生以及有一定 ...

  9. 移植UE4的模型操作到Unity中

    最近在Unity上要写一个东东,功能差不多就是在Unity编辑器上的旋转,移动这些,在手机上也能比较容易操作最好,原来用Axiom3D写过一个类似的,有许多位置并不好用,刚好在研究UE4的源码,在模型 ...

  10. Unity3d 在不同设备中的文件读写 的路径

    Application.dataPath : 数据路径   Unity Editor: <path tp project folder>/Assets Unity 编辑器:<工程文件 ...