超详细的Javascript事件循环模型之JS运行机制

一、前言

在上文《超详细的Javascript事件循环模型之同步和异步》中我们知道,JavaScript的运⾏顺序就是完全单线程的异步模型,也就是说,在同一个时间只能执行一个任务。这个任务通常是由事件循环机制控制的。当代码遇到异步操作时(如定时器、Ajax 请求等),它会将这个操作放入任务队列中,并继续执行下面的代码。当当前任务执行完毕后,事件循环会从任务队列中取出下一个任务并执行。也就是同步在前,异步在后。所有的异步任务都要等待当前的同步任务执⾏完毕之后才能执⾏。

那么为什么是这样的执行顺序呢?这个顺序地执⾏原理是什么样的呢?这⾥需要介绍⼀下浏览器中⼀个Tab⻚的实际线程组成。以Chrome浏览器为例,Chrome浏览器打开多个标签页,可以在 Chrome的任务管理器中看到有多个进程,分别是每一个Tab页面有一个独立的进程,以及一个主进程。 感兴趣的可以自行尝试下,如果再多打开一个Tab页,进程正常会多1个以上。注意,在这里浏览器应该也有自己的优化机制,有时候打开多个tab页后,可以在Chrome任务管理器中看到,有些进程被合并了,所以每一个Tab标签对应一个进程并不一定是绝对的。

二、JS的线程组成

线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。

虽然浏览器是单线程执⾏JavaScript代码的,但是浏览器实际是以多个线程协助操作来实现单线程异步模型的。JS的线程主要有:GUI渲染线程、JavaScript引擎线程、事件触发线程、定时器触发线程、HTTP请求线程。

1、GUI渲染线程
负责渲染浏览器界面,解析HTML,CSS,构建DOM树和RenderObject树,布局和绘制等。当界面需要重绘(Repaint)或由于某种操作引发回流(reflow)时,该线程就会执行。页面在第一次渲染的时候也会触发这个线程。

2、JavaScript引擎线程
也称为JS内核,负责处理Javascript脚本程序,例如V8引擎。JS引擎线程负责解析Javascript脚本,运行代码。JS引擎一直等待着任务队列中任务的到来,然后加以处理,浏览器无论什么时候都只有一个JS线程在运行JS程序,一个tab页中只有一个js线程在运行js程序。

注意:GUI渲染线程与JS引擎线程是互斥的,他们不能同时执行。当JS引擎执行时GUI线程会被挂起(相当于被冻结了),GUI更新会被保存在一个队列中等到JS引擎空闲时立即被执行。如果JS执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞。

3、事件触发线程
归属于浏览器而不是JS引擎,用来控制事件循环,可以理解,JS引擎自己都忙不过来,需要浏览器另开线程协助。

当JS引擎执行代码块如setTimeOut时(也可来自浏览器内核的其他线程,如鼠标点击、AJAX异步请求等),会将对应任务添加到事件线程中,当对应的事件符合触发条件被触发时,该线程会把事件添加到待处理队列的队尾,等待JS引擎的处理。
注意,由于JS的单线程关系,所以这些待处理队列中的事件都得排队等待JS引擎处理(当JS引擎空闲时才会去执行)。

4、定时器线程
定时器与计时器的线程,在满足条件之后会被添加到事件队列里边,等待js引擎空闲的时候去执行。浏览器定时计数器并不是由JavaScript引擎计数的,因为JavaScript引擎是单线程的, 如果处于阻塞线程状态就会影响记计时的准确,因此通过单独线程来计时并触发定时,计时完毕后,添加到事件队列中,等待JS引擎空闲后执行。

5、HTTP请求线程
在发送http请求的时候,这个线程会被执行。在有回调函数的时候,这个线程会把回调的事件放入到事件队列中去,等待js引擎执行。

按照真实的浏览器线程组成分析,会发现实际上运⾏JavaScript的线程其实并不是⼀个,但是为什么说JavaScript是单线程的呢?因为这些线程中实际参与代码执⾏的线程并不是所有线程,⽐如GUI渲染线程为什么单独存在,这个是防⽌在html⽹⻚渲染⼀半的时候突然执⾏了⼀段阻塞式的JS代码⽽导致⽹⻚卡在⼀半停住这种效果。在JavaScript代码运⾏的过程中实际执⾏程序时同时只存在⼀个活动线程,这⾥实现同步异步就是靠多线程切换的形式来进⾏实现的。

所以我们通常分析时,将上⾯的细分线程归纳为下列两条线程:

主线程:这个线程⽤来执⾏⻚⾯的渲染,JavaScript代码的运⾏,事件的触发等。

⼯作线程:这个线程是在幕后⼯作的,⽤来处理异步任务的执⾏来实现⾮阻塞的运⾏模式。

三、JS的运行模型

JavaScript 的运行机制是基于事件驱动模型的。当用户与页面交互时(如点击按钮、输入文本等),浏览器会生成相应的事件,并将其加入到事件队列中。JavaScript 通过监听这些事件来实现页面交互效果。

在这里插入图片描述

上图是JavaScript运⾏时的⼀个⼯作流程和内存划分的简要描述,我们根据图中可以得知主线程就是JavaScript执⾏代码的线程,主线程代码在运⾏时,会按照同步和异步代码将其分成两个去处,如果是同步代码执⾏,就会直接将该任务放在⼀个叫做“函数执⾏栈”的空间进⾏执⾏,执⾏栈是典型的栈结构,即先进后出,程序在运⾏的时候会将同步代码按顺序⼊栈,将异步代码放到⼯作线程中暂时挂起,⼯作线程中保存的是定时任务函数、JS的交互事件、JS的⽹络请求等耗时操作。当主线程将代码块筛选完毕后,进⼊执⾏栈的函数会按照从外到内的顺序依次运⾏,运⾏中涉及到的对象数据是在堆内存中进⾏保存和管理的。当执⾏栈内的任务全部执⾏完毕后,执⾏栈就会清空。执⾏栈清空后,“事件循环”就会⼯作,“事件循环”会检测任务队列中是否有要执⾏的任务,那么这个任务队列的任务来源就是⼯作线程,程序运⾏期间,⼯作线程会把到期的定时任务、返回数据的http任务等异步任务按照先后顺序插⼊到任务队列中,等执⾏栈清空后,事件循环会访问任务队列,将任务队列中存在的任务,按先进先出的顺序放在执⾏栈中继续执⾏,直到任务队列清空。

看上面的一段文字解释比较抽象,不容易理解。接下来将根据一段代码并结合图来解读js的实际运⾏思路。

function func1(){
  console.log('函数1')
}
function func2(){
  console.log('函数2')
}
function func3(){
  console.log('函数3')
}
function func4(){
  console.log('函数4')
}
func1()
setTimeout(func2,1000)
setTimeout(func3,500)
func4()

上面代码创建了四个函数代表4个任务,函数本身都是同步代码。在执⾏的时候会按照1,2,3,4进⾏解析,解析过程中我们发现func2和func3被setTimeout进⾏了定时托管,这样就只能先运⾏func1和func4了。当func1和func4运⾏完毕之后500ms后运⾏func3,1000ms后运⾏func2。

在这里插入图片描述

如上图,在上述代码刚开始运⾏的时候我们的主线程即将⼯作,按照顺序从上到下进⾏解释执⾏,此时执⾏栈、⼯作线程、任务队列都是空的,事件循环也没有⼯作。

在这里插入图片描述

如上图,可以看出程序在主线程执⾏之后就将func1、func4和func2、func3分别放进了两个⽅向,func1和func4都是⽴即执⾏任务所以会按照1->4的顺序进栈出栈(这⾥由于func1和2是平⾏任务所以会先执⾏func1的进出栈再执⾏func4的进出栈),⽽func2和func3由于是异步任务就会进⼊⼯作线程挂起并开始计时,并不影响主线程运⾏,此时的任务队列还是空置的。

在这里插入图片描述

如上图,可以看出同步任务的执⾏消耗时间非常短,当执⾏栈空置时,func2和func3还没有到时间,这样事件循环就会开始⼯作等待任务队列中的任务进⼊,接下来就是执⾏异步任务的时候了。

图片

如上图,发现任务队列并不是⼀下⼦就会将func2和func3⼀起放进去,⽽是哪个计时器到时间了哪个放进去,这样我们的事件循环就会发现队列中的任务,并且将任务拿到执⾏栈中进⾏消费,此时会输出func3的内容。

在这里插入图片描述

如上图,到这就是最后⼀次执⾏,当执⾏完毕后⼯作线程中没有计时任务,任务队列的任务清空程序到此执⾏完毕。

通过图解之后就会更清晰的知道异步任务的执⾏⽅式了,这⾥采⽤最简单的任务模型描绘复杂的任务在内存中的分配和⾛向,实际中是⾮常复杂的。

四、执行栈

执⾏栈是⼀个栈的数据结构,是一种后进先出(LIFO)的数据结构,当我们运⾏单层函数时,执⾏栈执⾏的函数进栈后,会出栈销毁然后下⼀个进栈下⼀个出栈,当有函数嵌套调⽤的时候栈中就会堆积栈帧。

当Javascript引擎开始执行第一行Javascript脚本代码的时候,它就会创建一个全局执行上下文然后将它压到执行栈中。每当引擎碰到一个函数的时候,它就会创建一个函数执行上下文,然后将这个执行上下文压到执行栈中。这种结构类似弹夹,执行栈就是弹夹,执行上下文是子弹,子弹被一个个压入弹夹,当子弹发射的时候,最后一个进弹夹的子弹会被最先射出。

引擎会执行位于执行栈栈顶的执行上下文(一般是函数执行上下文),当该函数执行结束后,对应的执行上下文就会被弹出,然后控制流程到达执行栈的下一个执行上下文。

以下面一段简单代码为例:

function func1(){
 console.log('func1执⾏')
 func2()
 console.log('func2执⾏完毕')
}

function func2(){
 console.log('func2执⾏')
 func3()
 console.log('func3执⾏完毕')
}

function func3(){
 console.log('func3执⾏')
}

func1()
console.log('func1执⾏完毕')

/*
func1执⾏
func2执⾏
func3执⾏
func3执⾏完毕
func2执⾏完毕
func1执⾏完毕
*/

上面代码执行过程如下:

在这里插入图片描述

第⼀次执⾏的时候调⽤func1函数执⾏到console.log的时候先进⾏输出,接下来会遇到func2函数的调⽤会出现下⾯的情况:

在这里插入图片描述

执⾏到此时检测到func2中还有调⽤func3的函数,那么就会继续进⼊func3中执⾏,如下图:

在这里插入图片描述

在执⾏完func3中的输出之后func3内部没有其他代码,那么func3函数执⾏完毕后就会发⽣出栈⼯作。

在这里插入图片描述

此时会发现func3出栈之后程序运⾏⼜会回到func2的函数中继续它的执⾏。

图片

接下来之后就剩下func1⾃⼰了,他在func2销毁之后输出“func2执⾏完毕”后它也会出栈并销毁。

图片

当func1执⾏完毕之后它随着销毁最后⼀⾏输出,就会进⼊执⾏栈执⾏并销毁,销毁之后执⾏栈和主线程清空。这个过程就会出现上面代码输出的这个顺序,⽽且我们在打印输出时,也能通过打印的顺序来理解⼊栈和出栈的顺序和流程。

五、递归

递归函数是项⽬开发时经常涉及到的场景,我们经常会在未知深度的树形结构,或其他合适的场景中使⽤递归。那么递归在⾯试中也会经常被问到⻛险问题,如果了解了执⾏栈的执⾏逻辑后,递归函数就可以看成是在⼀个函数中嵌套n层执⾏,那么在执⾏过程中会触发⼤量的栈帧堆积,如果处理的数据过⼤,会导致执⾏栈的⾼度不够放置新的栈帧,⽽造成栈溢出的错误。

执⾏栈的深度根据不同的浏览器和JS引擎有着不同的区别,我们这⾥就Chrome浏览器为例⼦来尝试⼀下递归的溢出。

let i = 0;

function func() {
  i++;
  console.log(`${i}次递归`);
  func()
}
func()

图片

发现在递归了10436次(每个人的电脑不同浏览器不同数值都不同)之后会提示“Uncaught RangeError: Maximum call stack size exceeded”超过栈深度的错误,也就是⽆法在Chrome或者其他浏览器做太深层的递归操作。

那么可以通过怎么样的技术手段跨越递归的限制呢?可以将代码做如下更改,这样就不会出现递归问题了。

let i = 0;

function func() {
  i++;
  console.log(`${i}次递归`);
  setTimeout(() => {
    func()
  }, 0)
}
func()

图片

可以看到控制台的输出发现超过了10436的界限也没有报错。我们只是做了⼀个小小的改造,这样就不会出现栈溢出的错误了。这是为什么呢?这个是因为这⾥使⽤了异步任务去调⽤递归中的函数,那么这个函数在执⾏的时候就不只使⽤栈进⾏执⾏了。

看下图没有异步任务调用时是这样的:

在这里插入图片描述

再看有异步任务调用时是这样的:

图片

有了异步任务之后递归就不会叠加栈帧了,因为放⼊⼯作线程之后该函数就结束了,可以出栈销毁,那么在执⾏栈中就永远都是只有⼀个任务在运⾏,这样就防⽌了栈帧的⽆限叠加,从⽽解决了⽆限递归的问题,不过异步递归的过程是⽆法保证运⾏速度的,在实际的⼯作场景中,如果考虑性能问题,还需要使⽤while循环等解决⽅案,来保证运⾏效率的问题,在实际⼯作场景中,尽量避免递归循环,因为递归循环就算控制在有限栈帧的叠加,其性能也远远不及指针循环。

六、后记

在知道了事件循环模型以及JavaScript的执⾏流程后,我们认识了⼀个叫做任务队列的容器,它的数据结构是队列的结构。所有除同步任务外的代码都会在⼯作线程中,按照它到达的时间节点有序的进⼊任务队列,⽽且任务队列中的异步任务⼜分为宏任务和微任务。这就是我们下篇文章重点介绍的内容——Javascript事件循环模型之宏任务和微任务。好了,本篇文章介绍到这里,欲知后事如何,请关注【前端技术营】,给你带来更多精彩内容。

  • 22
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
《精通JS脚本之ExtJS框架》由浅入深地讲解了ExtJS在Web开发中的相关技术。本书共分17章,分别介绍了JavaScript的对象编程、JavaScript浏览器对象模型和事件机制、ExtJS的核心类库和组件、ExtJS的事件处理方式、设计进度条、设计工具栏和菜单栏、设计面板、设计表格、设计表单、设计数据表、对Ajax的支持以及如何调试等。最后利用一个商品信息管理系统和一个企业任务管理系统,向读者演示了ExtJS在实际项目中的应用以及实现流程。   《精通JS脚本之ExtJS框架》附有配套光盘,提供了书中实例的源代码和视频教学文件。此外,读者还可以通过访问itzcn网站来获得即时在线帮助。   《精通JS脚本之ExtJS框架》可以作为Web开发的自学参考书,也可以作为RIA Web程序开发的培训教材。 第1章 JavaScript入门必备 1.1 JavaScript语言概述 1.1.1 JavaScript简介 1.1.2 JavaScript特点 1.1.3 JavaScript与Java 1.2 第一个JavaScript程序 1.2.1 嵌入JavaScript 1.2.2 链接外部JavaScript文件 1.2.3 注意事项 1.3 基础语法 1.3.1 数据类型 1.3.2 变量与常量 1.3.3 运算符 1.4 流程控制语句 1.4.1 if条件语句 1.4.2 switch条件语句 1.4.3 while循环语句 1.4.4 do while循环语句 1.4.5 for循环语句 1.4.6 for in循环语句 1.4.7 try catch finally语句 1.4.8 其他语句 第2章 JavaScript浏览器对象模型与事件处理 2.1 浏览器对象模型 2.1.1 文档对象 2.1.2 表单及其元素对象 2.1.3 浏览器信息对象 2.1.4 窗口对象 2.1.5 网址对象 2.1.6 历史记录对象 2.2 基本事件处理 2.3 2级DOM事件模型 2.3.1 事件传播 2.3.2 注册事件处理程序 2.3.3 event对象 2.4 常用事件 2.4.1 键盘事件 2.4.2 鼠标事件 2.4.3 页面事件 第3章 开始使用ExtJS 3.1 ExtJS概述 3.1.1 ExtJS简介 3.1.2 ExtJS中的基本概念 3.1.3 ExtJS与常见JavaScript库的介绍与对比 3.2 创建第一个程序 3.2.1 下载ExtJS 3.2.2 部署到开发工具中 3.2.3 编写HelloWorld.html 3.2.4 运行调试ExtJS 3.3 辅助开发 3.3.1 调试工具Firebug 3.3.2 开发利器Spket 第4章 ExtJS事件机制 4.1 设计模式——观察者模式 4.2 自定义事件 4.3 浏览器事件 4.4 ExtJS中的事件 4.4.1 Function.call()/apply()方法 4.4.2 函数的作用域 4.4.3 Ext.lib.Event事件 4.4.4 Ext.util.Observable事件 4.4.5 Ext.EventManager事件 4.4.6 Ext.EventObject事件 4.5 各种事件登记方式 4.5.1 传统式登记 4.5.2 内联式登记 4.5.3 Dom Level2登记 4.6 高级组件事件 4.7 ExtJS键盘事件 第5章 ExtJS组件 5.1 核心组件 5.1.1 ExtJS组件结构 5.1.2 Ext.Component 5.1.3 Ext.BoxComponent 5.1.4 Ext.Container 5.1.5 Ext.Panel 5.1.6 Ext.TabPanel 5.2 信息提示框组件 5.2.1 Ext.MessageBox简介 5.2.2 Ext.MessageBox.alert() 5.2.3 Ext.MessageBox.confirm() 5.2.4 Ext.MessageBox.prompt() 5.2.5 Ext.MessageBox.wait() 5.2.6 Ext.MessageBox.show() 5.2.7 Ext.MessageBox的其他功能 5.3 进度条组件 5.3.1 Ext.ProgressBar简介 5.3.2 手工模式的进度条 5.3.3 自动模式的进度条 5.3.4 自定义样式的进度条 5.4 工具栏和菜单栏 5.4.1 Ext.Toolbar简介 5.4.2 只包含按钮的简单工具栏 5.4.3 包含多种元素的复杂工具栏 5.4.4 Ext.menu.Menu简介 5.4.5 最简单的菜单栏 5.4.6 创建三级或多级菜单 5.4.7 具有选择框的菜单 第6章 页面元素与模板 6.1 构成用户界面的元素 6.2 获取页面元素 6.3 元素常见的使用方法 6.3.1 常见的“显示/隐藏”方法 6.3.2 常见的“内容控制”方法 6.3.3 常见的“操控DOM”方法 6.3.4 常见的“尺寸大小/定位”方法 6.3.5 常见的“特效动画”方法 6.3.6 DomHelper简介 6.4 DomQuery入门 6.4.1 元素选择符Selector 6.4.2 属性选择符Attributes Selectors 6.4.3 CSS值元素选择符 6.4.4 Ext.query与Ext.select 6.5 应用模板 6.5.1 Ext.Template 6.5.2 Ext.XTemplate 第7章 设计表单类布局 7.1 Form表单简介 7.1.1 Form表单的基本配置 7.1.2 ExtJS对Form表单的封装 7.2 ExtJS的表单组件 7.2.1 文本输入控件Ext.form.TextField 7.2.2 多行文本输入控件Ext.form.TextArea 7.2.3 单选框 7.2.4 复选框 7.2.5 下拉列表框 7.2.6 日期输入控件Ext.form.DateField 7.2.7 在线编辑器Ext.form.HtmlEditor 7.3 ExtJS表单组件的综合应用 第8章 设计表格类布局 8.1 表格简介 8.1.1 表格的基本属性 8.1.2 制作第一个表格 8.2 表格常用功能详解 8.2.1 主要属性功能 8.2.2 自定义列宽度 8.2.3 执行按列排序 8.2.4 解决中文排序 8.2.5 格式化显示日期类型数据 8.3 美化表格 8.4 设置表格背景颜色 8.5 显示行号和复选框 8.5.1 显示行号 8.5.2 引用复选框 第9章 表格的高级功能 9.1 表格视图——Ext.grid.GridView 9.2 表格分页 9.2.1 添加表格分页显示工具条 9.2.2 从后台脚本获得分页数据 9.2.3 在表格顶部显示分页工具条 9.2.4 实现前台分页效果 9.3 可编辑表格控件——EditorGrid 9.3.1 制作第一个EditorGrid 9.3.2 添加一行数据 9.3.3 保存修改结果 9.3.4 验证EditGrid中的数据 9.3.5 限制输入数据的类型 9.4 PropertyGrid属性表格控件 9.4.1 PropertyGrid简介 9.4.2 只读的PropertyGrid 9.4.3 对name列强制排序并获得value 9.4.4 自定义编辑器 9.5 分组表格控件——Group 9.5.1 分组表格简介 9.5.2 Ext.grid.GroupingView的配置操作 9.6 可拖放的表格 9.6.1 拖放改变表格的大小 9.6.2 在同一个表格里拖放 9.6.3 表格之间的拖放 9.6.4 表格与树之间的拖放 第10章 设计树状结构布局 10.1 TreePanel的基本使用 10.1.1 创建一棵树 10.1.2 为树生枝展叶 10.1.3 树形的配置 10.1.4 使用TreeLoader获得数据 10.1.5 读取本地JSON数据 10.2 树的事件 10.3 右键菜单 10.4 修改节点的默认图标 10.5 从节点弹出对话框 10.6 节点提示信息 10.7 为节点设置链接 10.8 树形的拖放 10.8.1 节点拖放的3种形式 10.8.2 叶子不能append 10.8.3 判断拖放的目标 10.8.4 树之间的拖放 10.9 树形过滤器TreeFilter 10.10 利用TreeSorter对树进行排序 10.11 树形节点视图——Ext.tree.TreeNodeUI 10.12 表格与树形的结合——Ext.ux.tree.ColumnTree 第11章 其他布局类简介 11.1 标准布局类 11.1.1 折叠布局——AccordionLayout 11.1.2 边框布局——BorderLayout 11.1.3 卡片式布局——CardLayout 11.1.4 列布局——ColoumnLayout 11.1.5 锚点布局——AnchorLayout 11.1.6 自适应布局——FitLayout 11.1.7 ContainerLayout 11.2 与布局有关的其他知识 11.2.1 父类Ext.Container公共配置与xtype的概念 11.2.2 使用Viewport 11.2.3 实现表单元素横排 第12章 ExtJS对Ajax的支持 12.1 Ext.Ajax介绍 12.1.1 Ext.Ajax.request方法详解 12.1.2 Ext.Ajax.request操作示例 12.1.3 Ext.Ajax.request提交XML数据 12.2 Ext.Updater基础 12.2.1 Ext.Updater.update方法 12.2.2 Ext.Updater.update操作示例 12.3 利用Ajax优化Web应用框架 12.3.1 多级联动菜单 12.3.2 Ajax修改用户密码 12.3.3 自动保存的网络记事本 12.3.4 网页计算器 第13章 设计数据驱动模式 13.1 XML/JSON数据格式比较 13.2 容器类MixedCollection 13.3 数据存储基本单元Record与dataField 13.3.1 dataField 13.3.2 Record 13.4 数据存储store 13.4.1 数据载入 13.4.2 对数据进行排序 13.4.3 从store 中获取数据 13.4.4 更新store 中的数据 13.4.5 加载及显示数据 13.5 数据代理 13.5.1 Ext.data.DataProxy 13.5.2 Ext.data.MemoryProxy 13.5.3 Ext.data.HttpProxy 13.5.4 Ext.data.ScriptTagProxy 13.6 数据读取器 13.6.1 Ext.data.DataReader 13.6.2 Ext.data.ArrayReader 13.6.3 Ext.data.JsonReader 13.6.4 Ext.data.XmlReader 13.7 Ext.ux.DWR 13.7.1 Ext.data.DwrProxy 13.7.2 Ext.data.DWRTreeLoader 13.7.4 Web服务端配置 13.7.5 服务层接口 第14章 ExtJS扩展 14.1 利用Ext.extend实现继承 14.2 与ExtJS扩展相关的预备知识 14.2.1 定义命名空间 14.2.2 使用xtype 14.3 用户扩展和插件 14.3.1 编写自定义用户扩展 14.3.2 常用插件UploadDialog 14.3.3 常用插件ManagedIFrame 14.4 使用ExtJS制作Flash统计报表 14.4.1 柱状图 14.4.2 折线图 14.4.3 饼状图 14.4.4 柱状栈图 第15章 调试JavaScript与HTML 15.1 Firebug的基本使用 15.1.1 开启或关闭Firebug 15.1.2 控制台 15.2 Firebug的应用 15.2.1 源代码调试 15.2.2 CSS调试 15.2.3 脚本调试 15.3 跟踪网络传输状态 15.4 在脚本文件中加入调试命令 15.5 在IE中使用Firebug 15.5.1 前端调试利器DebugBar 15.5.2 IE下的优秀JavaScript调试工具Companion.JS 15.5.3 DebugBar和Companion.JS的基本操作 15.6 调试技巧 15.6.1 在Firebug中直接调试脚本 15.6.2 调试代码运行速度 15.6.3 查看对象属性 第16章 ExtJS案例:商品信息管理系统 16.1 商品信息管理系统功能介绍 16.2 数据库设计和实现 16.2.1 数据库概念结构设计 16.2.2 数据库表设计 16.3 为项目做好准备 16.4 登录界面 16.5 栏目加载 16.6 为项目换肤 16.7 商品信息管理 16.7.1 商品信息的查询 16.7.2 商品信息的添加 16.7.3 商品信息的删除 16.7.4 商品信息的更新 第17章 ExtJS案例:企业任务管理系统 17.1 系统概述 17.2 需求分析 17.3 数据库设计 17.4 员工任务管理 17.4.1 个人任务处理 17.4.2 个人资料编辑 17.5 主管任务管理 17.5.1 部门计划处理 17.5.2 部门人员管理 17.6 系统管理员权限分配
javascript完全自学手册 目 录 第1篇 JavaScript基础篇 第1章 JavaScript简介 1 1.1 JavaScript概述 1 1.1.1 什么是JavaScript 1 1.1.2 JavaScript的基本特点 2 1.1.3 常用的Web开发语言 3 1.2 JavaScript的应用 4 1.2.1 客户端应用 5 1.2.2 服务器端应用 5 1.3 在Web页面中使用JavaScript 5 1.3.1 HTML的基本结构 5 1.3.2 在HTML中嵌入JavaScript 7 1.3.3 链接JavaScript文件 9 1.4 编写JavaScript的工具 11 1.4.1 使用纯文本编辑器 11 1.4.2 使用专业化脚本编辑工具 13 1.4.3 使用Microsoft脚本编辑器 15 第2章 JavaScript编程基础 19 2.1 基础语法 19 2.1.1 数据类型 19 2.1.2 变量和常量 22 2.1.3 表达式 24 2.1.4 运算符 24 2.2 流程控制 27 2.2.1 条件语句 27 2.2.2 循环语句 30 2.2.3 其他语句 35 2.3 使用对话框 38 2.3.1 警告对话框 38 2.3.2 确认对话框 40 2.3.3 提示对话框 40 第2篇 JavaScript内置对象篇 第3章 JavaScript内置对象 43 3.1 JavaScript对象概述 43 3.1.1 对象的概念 43 3.1.2 使用JavaScript对象 基础知识 44 3.2 Array对象 46 3.2.1 创建Array对象 46 3.2.2 Array对象属性 47 3.2.3 Array对象方法 48 3.3 String对象 51 3.3.1 创建String对象 51 3.3.2 String对象属性 51 3.3.3 String对象方法 53 3.4 Math对象 56 3.5 Date对象 62 3.5.1 Date对象方法 62 3.5.2 使用Date对象 63 3.6 自定义对象 67 第4章 JavaScript常用对象 73 4.1 Document对象 73 4.1.1 Document对象概述 73 4.1.2 使用Document对象 75 4.2 Form对象及其元素 79 4.2.1 Form对象概述 79 4.2.2 表单元素 80 4.2.3 表单元素属性和事件 82 4.2.4 表单验证 85 4.3 Anchor与Link对象 89 4.3.1 Anchor对象 89 4.3.2 Link对象 90 4.4 Image对象 92 4.4.1 图像翻转 92 4.4.2 图像载入 92 第5章 JavaScript其他常用 窗口对象 96 5.1 Window对象 96 5.1.1 常用属性和方法 97 5.1.2 多窗口控制 100 5.2 Screen对象 103 5.3 Navigator对象 105 5.4 Location对象 107 5.4.1 常用属性和方法 107 5.4.2 Location对象的应用实例 109 5.5 History对象 112 5.5.1 常用属性和方法 112 5.5.2 History对象的应用实例 113 5.6 Frame对象 115 5.6.1 Frame对象概述 115 5.6.2 常用属性 116 5.6.3 Frame对象的应用实例 117 第6章 DOM对象 122 6.1 DOM概述 122 6.1.1 DOM简介 122 6.1.2 DOM与HTML文档 124 6.2 DOM对象 125 6.2.1 DOM基本接口 125 6.2.2 DOM基本对象 128 6.3 使用DOM 128 6.3.1 DOM基础 129 6.3.2 Node和NodeList接口 131 6.3.3 Element接口 134 6.3.4 Text接口和Attr接口 136 6.4 操作HTML文档 138 6.4.1 访问元素 138 6.4.2 添加节点 140 6.4.3 删除节点 142 6.4.4 对属性进行操作 146 第3篇 JavaScript高级编程篇 第7章 正则表达式 151 7.1 正则表达式及其作用 151 7.2 正则表达式参考语法 152 7.2.1 限定符 154 7.2.2 选择匹配符 157 7.2.3 分组组合
目录 第1篇 JavaScript基础篇 第1章 JavaScript简介 1.1 JavaScript概述 1.1.1 什么是JavaScript 1.1.2 JavaScfipt的基本特点 1.1.3 常用的Web开发语言 1.2 JavaScript的应用 1.2.1 客户端应用 1.2.2 服务器端应用 1.3 在web页面中使用JavaScript 1.3.1 HTML的基本结构 1.3.2 在HTML中嵌入JavaScript 1.3.3 链接JavaScript文件 1.4 编写JavaScript的工具 1.4.1 使用纯文本编辑器 1.4.2 使用专业化脚本编辑工具 1.4.3 使用Microsoft脚本编辑器 第2章 JavaScript编程基础 2.1 基础语法 2.1.1 数据类型 2.1.2 变量和常量 2.1.3 表达式 2.1.4 运算符 2.2 流程控制 2.2.1 条件语句r 2.2.2 循环语句 2.2.3 其他语句 2.3 使用对话框 2.3.1 警告对话框 2.3.2 确认对话框 2.3.3 提示对话框 第2篇 JavaScript内置对象篇 第3章 JavaScript内置对象 3.1 JavaScript对象概述 3.1.1 对象的概念 3.1.2 使用JavaScript对象基础知识 3.2 Array对象 3.2.1 创建Array对象 3.2.2 Array对象属性 3.2.3 Array对象方法 3.3 String对象 3.3.1 创建String对象 3.3.2 String对象属性 3.3.3 String对象方法 3.4 Math对象 3.5 Date对象 3.5.1 Date对象方法 3.5.2 使用Date对象 3.6 自定义对象 第4章 JavaScript常用对象 4.1 Document对象 4.1.1 Document对象概述 4.1.2 使用Document对象 4.2 Form对象及其元素 4.2.1 Form对象概述 4.2.2 表单元素 4.2.3 表单元素属性和事件 4.2.4 表单验证 4.3 Anchor与Link对象 4.3.1 Anchor对象 4.3.2 Link对象 4.4 Image对象 4.4.1 图像翻转 4.4.2 图像载入 第5章 JavaScnpt其他常用窗口对象 5.1 Window对象 5.1.1 常用属性和方法 5.1.2 多窗口控制 5.2 Screen对象 5.3 Navigator对象 5.4 Location对象 5.4.1 常用属性和方法 5.4.2 Location对象的应用实例 5.5 History对象 5.5.1 常用属性和方法 5.5.2 History对象的应用实例 5.6 Frame对象 5.6.1 Frame对象概述 5.6.2 常用属性 5.6.3 Frame对象的应用实例 第6章 DoM对象 6.1 DOM概述 6.1.1 DOM简介 6.1.2 DOM与HTML文档 6.2 DOM对象 6.2.1 DOM基本接口 6.2.2 DOM基本对象 6.3 使用DOM 6.3.1 DOM基础 6.3.2 Node和NodeList接口 6.3.3 Element接口 6.3.4 Text接口和Attr接口 6.4 操作HTML文档 6.4.1 访问元素 6.4..2 添加节点 6.4.3 删除节点 6.4.4 对属性进行操作 第3篇 JavaScript高级编程篇 第7章 正则表达式 7.1 正则表达式及其作用 7.2 正则表达式参考语法 7.2.1 限定符 7.2.2 选择匹配符 7.2.3 分组组合和反向引用符 7.2.4 特殊字符 7.2.5 字符匹配符 7.2.6 定位符 7.2.7 原义字符 7.3 RegExp对象 7.3.1 创建RegExp对象实例的两种方式 7.3.2 RegExp对象的属性 7.3.3 RegExp对象的方法 7.4 String对象中与正则表达式有关的方法 第8章 高级DoM技术 8.1 CSS样式 8.1.1 CSS语法 8.1.2 CSS属性 8.2 样式控制 8.2.1 Style对象 8.2.2 使用CSS属性 8.2.3 自定义鼠标提示 8.2.4 可折叠区域 8.3 StyleSheet对象 8.3.1 StyleSheet对象的属性 8.3.2 StyleSheet对象的方法 8.4 修改内容 8.5 实例应用 8.5.1 制作动态新闻框 8.5.2 显示当前日期 8.5.3 进度条控制滚动图片 8.5.4 百叶窗效果 8.5.5 更改表格间隔背景色 第9章 JavaScript中的XML 9.1 XML语言 9.1.1 XML概述 9.1.2 XML文档结构 9.1.3 XML标记 9.1.4 XML文档元素 9.1.5 XML属性 9.1.6 XML命名空间 9.2 XMLDOM 9.2.1 通用接口 9.2.2 IE中的XMLDOM支持 9.2.3 Mozilla中XMLDOM支持 9.2.4 XMLDOM实例 9.3 XPath 9.3.1 XPath概述 9.3.2 IE中的XPath支持 9.3.3 Mozilla中的XPath支持 9.4 XSLT 9.4.1 XSLT概述 9.4.2 IE中的XSLT支持 9.4.3 MozilIa中XSLT支持 9.5 数据岛技术 第10章 JavaScript事件处理 10.1 事件概述 10.1.1 事件简介 10.1.2 指定事件 10.2 原始事件模型 10.2.1 事件类型 10.2.2 使用事件返回值 10.2.3 使用事件this关键字 10.2.4 使用属性处理事件 10.2.5 使用JavaScript处理事件 10.3 标准事件模型 10.3.1 事件传播 10.3.2 注册事件处理程序 10.3.3 设置对象的事件处理程序 10.3.4 事件的模块和类型 10.3.5 Event接口和对象 10.4 IE事件模型 10.4.1 IEEvent对象 10.4.2 IE的事件传播 10.5 常用事件 10.5.1 鼠标事件 10.5.2 键盘事件 10.5.3 表单事件 10.5.4 编辑事件 10.5.5 页面事件 第11章 使用Cookie和文件 11.1 Cookie 11.1.1 Cookie概述 11.1.2 Cookie属性 11.1.3 创建Cookie 11.1.4 读取Cookie 11.1.5 删除Cookie 11.1.6 在客户机设置Cookie 11.1.7 保存用户登录状态 11.2 文件处理 11.2.1 FileSystemObjeet对象 11.2.2 Drive对象 11.2.3 Folder对象 11.2.4 File对象 11.2.5 资源管理器 第12章 JavaScript与Ajax 12.1 Ajax概述 12.1.1 Ajax运行机制 12.1.2 A1ax技术优势 12.2 Ajax核心技术 12.2.1 JavaSeript 12.2.2 DOM 12.2.3 XML 12.2.4 XMLHtlpRequest 12.3 使用Ajax 12.3.1 创建XMLHttp,Request对象 12.3.2 获取XMLHttp,Request对象的信息 12.3.3 向服务器发送请求 12.3.4 处理服务器响应 12.3.5 用户注册实例 12.3.6 处理XML请求 12.3.7 动态列表 第13章 JavaScript安全与异常处理 13.1 JavaScript安全 13.1.1 域策略 13.1.2 IntemetExplorer安全区域 13.2 IE浏览器内建的错误报告 13.3 异常处理 13.3.1 异常类型 13.3.2 触发onError事件处理异常 13.3.3 使用trycatch语句处理异常 13.3.4 Error对象 13.3.5 使用throw语句 13.4 JavaScript调试技法 13.4.1 使用alen()语句 13.4.2 使用write()语句 13.4.3 抛出自定义异常消息 第4篇 JaVflscript特效应用 第14章 JavaScript网页特效 14.1 文字特效 14.1.1 文字向上不间断无缝滚动 14.1 12灼热的文字(IE) 14.1.3 标题栏文字循环向左移动 14.1.4 各种形式输出文字 14.1.5 跑马灯式说明文字 14.1.6 跳动的文字 14.2 图片特效 14.2.1 线性幻灯片 14.2.2 非线性幻灯片 14.2.3 展示翻页效果 14.2.4 展示缩略图新闻效果 14.2.5 图片滑动效果 14.2.6 三维相册 14.3 时间特效 14.3.1 时钟提示自动关闭 14.3.2 日历生成器 14.4 窗口特效 14.4.1 窗口拖动 14.4.2 图层受标签控制显示 14.5 鼠标特效 14.5.1 鼠标方向提示 14.5.2 鼠标控制页面上下移动 14.6 菜单特效 14.6.1 树状菜单 14.6.2 折叠菜单 14.6.3 滑动菜单 14.6.4 右键菜单 ……

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值