深入理解JavaScript特性

最近在读《JavaScript高级程序设计》这一本书,里面提到了JavaScript的特征,倍感兴趣,于是结合自己的认识,在这里进行一下总结。

1、JavaScript的垃圾回收机制

javaScript中的5种数据类型存放在栈中(Undefined、Null、Boolean、Number、String),非基本数据类型存放在堆中,占用内存,堆不会被程序自动释放。

一张图看懂JS中数据类型的存放位置:基本数据类型存放在栈中,非基本数据类型存放在堆中(对象),变量obi1在栈中存储的只是堆中对象的地址。

声明变量a=对象,只是声明一个指针地址指向存储该对象的内存空间,每多一个指向同一内存空间的指针地址,该对象的引用计数就会加1。

如果代码在运行过程中有一个对象不再被需要了,但是引用计数不为零,垃圾回收机制就不能释放这块内存,这就被称为内存泄漏。

释放内存的方法就是 接触对该内存地址的引用,将引用他的指针地址设置为null,如:a=null;

2、JavaScript 单线程(同一个时间只能做一件事)核心特征

JS除了主线程之外还存在一个任务队列,(js单线程所有任务必须排队完成)。

js计算能力很弱如果存在一个耗时较长的任务,后一个任务就必须等待很长时间让前一个任务执行完毕,,如果是网络请求他的耗时完全取决于网络状况,(Ajax)不符合js设计逻辑。

主线程可以忽略io(input/output)设备,挂起处于等待中的任务(监听事件绑定的任务,ajax网络请求)先运行排在后面的任务,,等到io设备有了返回结果,再回过头把挂起任务执行下去 (异步事件)。

所有任务分两种synchronous同步事件asynchronous异步事件,在js中:

同步事件在主线程上排队执行(前一个执行完毕,后一个才能执行)。

异步事件不进入主线程,而进入任务队列(task queue),只有任务任务队列通知主线程,某个异步任务可以执行了,该任务才会从任务队列中取出进入主线程。

3、JavaScript运行机制步骤

(1)所有同步任务都在主线程上依次执行,形成(执行栈)。栈的定义:先进后出,后进先出。

举个例子:定义三个函数,sayHello函数直接在student函数体内调用,isAdult函数作为参数传给了sayHello函数,在这里isAdult也是一个回调函数。

三个函数进入执行栈的顺序依次是:student,sayHello,isAdult

        function student(){
            var age = 18;
            var name = ‘小李‘
            sayHello(name,age,isAdult(age))
            console.log("student函数")   //最后出栈
        }

        function isAdult(age){
            var result = age >= 18 ? ‘成年‘:‘未成年‘
            console.log("isAdult函数")   //最先出栈
            return result;
        }

        function sayHello(name,age,reust){
            console.log(‘hello!This is ‘+name+‘ ‘+age+‘years old 我‘ + reust)
            console.log("sayHello函数")
        }
        student();

看输出结果:三个函数进入执行栈的顺序依次是:isAdult,student,sayHello

(2)主线程之外,存在一个任务队列,只要异步任务有了返回结果,该任务就会被放入任务队列中。

(3)执行栈中所有任务执行完毕后,就会访问任务队列,检查队列中有哪些事件,获取任务队列中最先等待的事件,让该事件进入执行栈,开始执行。

(4)不断重复第三步。

4、JavaScript中回调函数callback(事件绑定函数)

例:绑定点击事件,当点击事件触发时 js会调用事件绑定的函数该函数称为事件的回调函数(异步任务必须指定回调函数)。

任务队列 先进先出数据结构,排在前面的事件会先被主线程读取,所以如果队列中有‘定时器‘,定时器未必准时触发,取决于前一个任务队列中的函数执行的结束。

5、JavaScript中内存区域

程序运行时,需要内存空间存放数据,分别为stack(栈)和heap(堆)。

栈是有结构的,每个区块按照一定的顺序取存放,可以明确的知道每个区块的大小,而堆是没有结构的,数据任意存放,因此栈的调用要快于堆。

每个线程分配一个栈,每个进程分配一个堆,stack是线程独占,heap是线程公用的。

栈是系统自动开辟的自动释放的, 堆是程序员手动开辟和释放的。

时间: 2024-09-30 00:50:56

深入理解JavaScript特性的相关文章

深入理解JavaScript中的属性和特性

深入理解JavaScript中的属性和特性? JavaScript中属性和特性是完全不同的两个概念,这里我将根据自己所学,来深入理解JavaScript中的属性和特性. 主要内容如下: 理解JavaScript中理解对象的本质.理解对象与类的关系.对象与引用类型的关系 对象属性如何进行分类 属性中特性的理解 第一部分:理解JavaScript中理解对象的本质.理解对象与类的关系.对象与引用类型的关系 对象的本质:ECMA-262把对象定义为:无序属性的集合,其属性可以包含基本值.对象或者函数.即

理解Javascript的动态语言特性

原文:理解Javascript的动态语言特性 Javascript是一种解释性语言,而并非编译性,它不能编译成二进制文件. 理解动态执行与闭包的概念 动态执行:javascript提供eval()函数,用于动态解释一段文本,并在当前上下文环境中执行. 首先我们需要理解的是eval()方法它有全局闭包和当前函数的闭包,比如如下代码,大家认为会输出什么呢? var i = 100; function myFunc() { var i = 'test'; eval('i = "hello."

深入理解JavaScript的闭包特性 如何给循环中的对象添加事件

初学者经常碰到的,即获取HTML元素集合,循环给元素添加事件.在事件响应函数中(event handler)获取对应的索引.但每次获取的都是最后一次循环的索引.原因是初学者并未理解JavaScript的闭包特性. 有个网友问了个问题,如下的html,为什么点击所有的段落p输出都是5,而不是alert出对应的0,1,2,3,4. <!DOCTYPE HTML> <html> <head> <meta charset="utf-8" /> &

(转)深入理解JavaScript的闭包特性 如何给循环中的对象添加事件

深入理解JavaScript的闭包特性如何给循环中的对象添加事件 初学者经常碰到的,即获取HTML元素集合,循环给元素添加事件.在事件响应函数中(event handler)获取对应的索引.但每次获取的都是最后一次循环的索引.原因是初学者并未理解JavaScript的闭包特性. 有个网友问了个问题,如下的html,为什么点击所有的段落p输出都是5,而不是alert出对应的0,1,2,3,4. 1.  <!DOCTYPE HTML> 2.  <html> 3.  <head&g

深入理解JavaScript的闭包特性如何给循环中的对象添加事件

初学者经常碰到的,即获取HTML元素集合,循环给元素添加事件.在事件响应函数中(event handler)获取对应的索引.但每次获取的都是最后一次循环的索引.原因是初学者并未理解JavaScript的闭包特性. 有个网友问了个问题,如下的html,为什么点击所有的段落p输出都是5,而不是alert出对应的0,1,2,3,4. 1.  <!DOCTYPE HTML> 2.  <html> 3.  <head> 4.  <meta charset="utf

深入理解JavaScript中创建对象模式的演变(原型)

创建对象的模式多种多样,但是各种模式又有怎样的利弊呢?有没有一种最为完美的模式呢?下面我将就以下几个方面来分析创建对象的几种模式: Object构造函数和对象字面量方法 工厂模式 自定义构造函数模式 原型模式 组合使用自定义构造函数模式和原型模式 动态原型模式.寄生构造函数模式.稳妥构造函数模式 第一部分:Object构造函数和对象字面量方法 我之前在博文<javascript中对象字面量的理解>中讲到过这两种方法,如何大家不熟悉,可以点进去看一看回顾一下.它们的优点是用来创建单个的对象非常方

深入理解JavaScript系列(1):编写高质量JavaScript代码的基本要点(转)

才华横溢的Stoyan Stefanov,在他写的由O’Reilly初版的新书<JavaScript Patterns>(JavaScript模式)中,我想要是为我们的读者贡献其摘要,那会是件很美妙的事情.具体一点就是编写高质量JavaScript的一些要素,例如避免全局变量,使用单变量声明,在循环中预缓存length(长度),遵循代码阅读,以及更多. 此摘要也包括一些与代码不太相关的习惯,但对整体代码的创建息息相关,包括撰写API文档.执行同行评审以及运行JSLint.这些习惯和最佳做法可以

深刻理解JavaScript基于原型的面向对象

主题一.原型 一.基于原型的语言的特点 1 只有对象,没有类;对象继承对象,而不是类继承类. 2  "原型对象"是基于原型语言的核心概念.原型对象是新对象的模板,它将自身的属性共享给新对象.一个对象不但可以享有自己创建时和运行时定义的属性,而且可以享有原型对象的属性. 3 除了语言原生的顶级对象,每一个对象都有自己的原型对象,所有对象构成一个树状的层级系统.root节点的顶层对象是一个语言原生的对象,其他所有对象都直接或间接继承它的属性. 显然,基于原型的语言比基于类的语言简单得多,我

理解JavaScript 的原型属性

1.原型继承 面向对象编程可以通过很多途径实现.其他的语言,比如 Java,使用基于类的模型实现: 类及对象实例区别对待.但在 JavaScript 中没有类的概念,取而代之的是一切皆对象.JavaScript 中的继承通过原型继承实现:一个对象直接从另一对象继承.对象中包含其继承体系中祖先的引用——对象的 prototype 属性. 2. JavaScript 实现继承的语言特性 当尝试访问 JavaScript 对象中不存在的属性时,解析器会查找匹配的对象原型.例如调用 car.toStri