• Javascript 简介


    1. Javascript 简介:

    Javascript是一种专为与网页交互而设计的脚本语言,由下列三个不同的部分组成:

    ECMAScript,由ECMA—262定义,提供核心语言功能;

    文档对象模型(DOM),提供访问和操作网页内容的方法和接口;

    浏览器对象模型(BOM),提供与浏览器交互的方法和接口。

    Javascript的这三个部分,在当前的五个浏览器中都得到了不同程度的支持。其中,所有浏览器对ECMAScript第三版的支持大体上都不错,但对DOM的支持则彼此相差比较多。对javascript中唯一尚无标准的BOM来说,尽管各浏览器都实现了某些众所周知的共同特性,但其他特性还是会因浏览器而异。

    1. 在HTML中使用javascript:

    把javascript插入到html页面中要使用<script>元素。使用这个元素可以把javascript嵌入到html页面中,让脚本与标记混合在一起,也可以包含外部的javascript文件。而我们需要注意的地方有:

    这两种使用方式都要求把type属性设置为text/javascript,以表明使用的脚本语言是javascript。

    在包含外部javascript文件时,必须将src属性设置为指向相应文件的URL。而这个文件既可以是与包含它的页面位于同一服务器上的文件,也可以是其他任何域中的文件。

    所有<script>元素会按照他们在页面中出现的先后顺序依次被解析。只有在解析万前面<script>元素中的代码之后,才会开始解析后面<script>元素中的代码。

    浏览器在呈现后面的页面内容前,必须先解析完前面<script>元素中的代码。为此,一般要把<script>元素放在页面的末尾,放在页面内容之后和结束的</body>标签之前。

    在IE中,可以通过设置defer属性让浏览器在呈现完文档之后再执行脚本。虽然defer属性是html4.01中规定的,但只有IE支持该属性。

    另外,使用<noscript>元素可以指定在不支持脚本的浏览器中显示的替代内容。但在启用了脚本的情况下,浏览器不会显示<noscript>元素中的任何内容。

    1. 基本概念:

    Javascript的核心语言特性在ECMA-262中是以名为ECMAScript的伪语言形式来定义的。ECMAScript中包含了所有基本的语法,操作符,数据类型以及完成基本的计算任务所必须的对象,但没有对取得输入和产生输出的机制做出规定。理解ECMAScript及其纷繁复杂的各种细节,是理解其在web浏览器中的实现—javascript的关键。目前大多数实现所遵行的都是ECMA-262第三版中定义的ECMAScript。以下简要总结了ECMAScript中基本的要素:

    ECMAScript中的基本数据类型包括undefined,null,boolean,number和string;

    与其他语言不同,ECMAScript没有为整数和浮点数分别定义不同的数据类型,number类型可用于表示所有的数值;

    ECMAScript中也有一种复杂的数据类型,即object类型,这类型是这门语言中所有对象的基础类型;

    ECMAScript提供了很多与c及其他类c语言中相同的基本操作符,包括算术操作符,布尔操作符,关系操作符,相等操作符及赋值操作符等等;

    ECMAScript从其他语言中借鉴了很多流控制语句,例如if语句,for语句和switch语句等。

    ECMAScript中的函数与其他语言中的函数有诸多不同之处。

    无需指定函数的返回值,因为任何ECMAScript函数都可以在任何时候返回任何值。

    实际上,未指定返回值的函数返回的是一个特殊的undefined值。ECMAScript中也没有函数签名的概念,因为其函数参数是以一个包含零或多个值的数组的形式传递的。

    可以向ECMAScript函数传递任意数量的参数,并且可以通过arguments对象来访问这些参数。

    由于不存在函数签名的特性,ECMAScript函数不能重载。

    1. 变量,作用域和内存问题:

    Javacript变量可以用来保存两种类型的值:基本类型值和引用类型值。基本类型的值源自以下5种基本数据类型:undefined,null,boolean,number和string。基本类型值和引用类型值具有以下特点:

    基本类型值在内存中占据固定大小的空间,因此被保存在栈内存中;

    从一个变量向另一个变量复制基本类型的值,会创建这个值的一个副本;

    引用类型的值是对象,保存在堆内存中;

    包含引用类型值的变量实际上包含的不是对象本身,而是一个指向该对象的指针;

    从一个变量向另一个变量复制引用类型的值,复制的其实是指针,因此两个变量最终都指向同一个对象;

    确定一个值是哪种基本类型可以使用typeof操作符,而确定一个值是哪种引用类型可以使用instanceof操作符;

    所有变量(包括基本类型和引用类型)都存在于一个执行环境(也称作作用域)当中,这个执行环境决定了变量的生命周期,以及哪一部份代码可以访问其中的变量。以下是关于执行环境的几点总结:

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

    每次进入一个新执行环境,都会创建一个用于搜索变量和函数的作用域链;

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

    全局环境只能访问在全局环境中定义的变量和函数,而不能直接访问局部环境中的任何数据;

    变量的执行环境有助于确定应该何时释放内存。

    Javascript是一门具有自动垃圾回收机制的编程语言,开发人员不必关心内存分配和回收问题。可以对javascript的垃圾收集例程做如下总结:

    离开作用域的值将被自动标记为可以回收,因此将在垃圾收集期间被删除,

    标记清除是目前主流的垃圾收集算法,这种算法的思想是给当前不使用的值加上标记,然后再回收其内存。

    另一种垃圾收集算法是“引用计数”,这种算法的思想是跟踪记录所有值被引用的次数。

    目前不再使用这种算法,但在ie 中访问非原生javascript对象(如DOM元素)时,这种算法仍可能导致问题。

    当代码中存在循环引用现象时,“引用计数”算法就会导致问题。

    解除变量的引用不仅有助于消除循环引用现象,而且对垃圾收集也有好处。为了确保有效的回收内存,应该及时解除不再使用的全局对象,全局对象属性以及循环引用变量的引用。

    1. 引用类型:

    对象在javascript中被称为引用类型的值,而且有一些内置的引用类型可以用来创建特定的对象,现在简要总结如下:

    引用类型与传统面向对象程序设计中的类相似,但实现不同;

    • object是一个基础类型,其他所有类型都从object继承了基本的行为;

    array类型是一组值的有序列表,同时还提供了操作和转换这些值的功能;

    date类型提供了有关日期和时间的信息,包括当前日期和时间以及相关的计算功能;

    regexp类型是ECMAScript支持正则表达式的一个接口,提供了最基本的和一些高级的正则表达式功能。

    函数实际上是function类型的实例,因此函数也是对象;而这一点正是javascript最有特色的地方,由于函数是对象,所以函数也拥有方法,可以用来增强其行为。

    因为有了基本包装类型,所以javascript中的基本类型值可以被当作对象来访问。三种基本包装类型分别是:boolean,number,string 。以下是他们共同的特征:

    每个包装类型都映射到同名的基本类型;

    在读取模式下访问基本类型值时,就会创建对应的基本包装类型的一个对象,从而方便了数据操作;

    操作基本类型值的语句一经执行完毕,就会立即销毁新创建的包装对象。

    在所有代码执行之前,作用域中就已经存在两个内置对象:global和math。在大多数ECMAScript实现中都不能直接访问global对象;不过,web浏览器实现了承担该角色的window对象。全局变量和函数都是global对象的属性。Math对象提供了很多属性和方法,用于辅助完成复杂的数学计算任务。

    1. 面向对象的程序设计:

    ECMAScript支持面向对象(oo)编程,但不使用类或接口。对象可以在代码执行过程中创建和增强,因此具有动态性而非严格定义的实体。在没有类的情况下,可以采用下列模式创建对象。

    工厂模式,使用简单的函数创建对象,为对象添加属性和方法,然后返回对象。这个模式后来被构造函数模式所取代。

    构造函数模式,可以创建自定义引用类型,可以象创建内置对象实例一样使用new操作符。不过,构造函数模式也有缺点,即它的每个成员都无法得到复用,包括函数。由于函数可以不局限于任何对象(即与对象具有松散耦合的特点),因此没有理由不在多个对象间共享函数。

    原型模式,使用构造函数的prototype属性来指定那些应该共享的属性和方法。组合使用构造函数模式和原型模式时,使用构造函数定义实例属性,而使用原型定义共享的属性和方法。

    Javascript主要通过原型链实现继承,原型链的构建是通过将一个类型的实例赋值给另一个构造函数的原型实现的。这样,子类型就能访问超类型的所有属性和方法,这一点与机遇类的继承很相似。原型链的问题是对象实例共享所有继承的属性和方法,因此不适合单独使用。解决这个问题的技术是借用构造函数,即在子类型构造函数的内部调用超类型的构造函数。这样就可以做到每个实例都具有自己的属性,同时还能保证只使用构造函数模式来定义类型。使用最多的继承模式是组合继承,这种模式使用原型链继承共享的属性和方法,而通过借用构造函数继承实例属性。

    此外,还存在下列可供选择的继承模式。

    原型式继承,可以在不必预先定义构造函数的情况下实现继承,其本质是执行对给定对象的浅复制。而复制得到的副本还可以得到进一步改造。

    寄生式继承,与原型式继承非常相似,也是基于某个对象或某些信息创建一个对象,然后增强对象,最后返回对象。为了解决组合继承模式由于多次调用超类型构造函数而导致的低效率问题,可以将这个模式与组合继承一起使用。

    寄生组合式继承,集寄生式继承和组合继承的优点与一身,是实现基于类型继承的最有效的方式。

    1. 匿名函数,也称为拉姆达函数,是一种使用javascript函数的强大方式,以下总结了匿名函数的特点:

    任何函数表达式从技术上说都是匿名函数,因为没有引用他们的确定方式;

    在无法确定如何引用函数的情况下,递归函数会变得很复杂;

    递归函数应该始终使用arguments.callee来递归的调用自身,不要使用函数名---函数名可能会发生变化。

    当在函数内部定义了其他函数时,就创建闭包。闭包有权访问包含函数内部的所有变量,原理如下:

    在后台执行环境中,闭包的作用域链包含着它自己的作用域链,包含函数的作用域和全局作用域。

    通常,函数的作用域集齐所有变量都会在函数执行结束后被销毁;

    但是,当函数返回一个闭包时,这个函数的作用域将会一直在内存中保存到闭包不存在为止;

    使用闭包可以在javascript中模仿块级作用域,要点如下:

    创建并立即调用一个函数,这样既可以执行其中的代码,又不会在内存中留下对该函数的引用;结果就是函数内部的所有变量都会被立即销毁—除非将某些变量赋值给了包含作用域(外部作用域)中的变量。

    闭包还可以用于在对象中创建私有变量,相关概念和要点如下:

    即使javascript中没有正式的私有对象属性的概念,但可以使用闭包来实现公有方法,而通过公有方法可以访问在包含作用域中定义的变量;

    有权访问私有变量的公有方法叫做特权方法;

    可以使用构造函数模式,原型模式来实现自定义类型的特权方法,也可以使用模块模式,增强的模块模式来实现单例的特权方法。

    Javascript中的匿名函数和闭包都是非常有用的特性,利用它们可以实现很多功能。不过,因为创建闭包必须维护额外的作用域,所以过度使用它们可能会占用大量内存。

    1. BOM:

    浏览器对象模型(BOM)以window对象为依托,表示浏览器窗口及其页面可见区域。同时,window对象还是ECMAScript中的global对象,因而所有全局变量和函数都是它的属性,且所有原生的构造函数及其他函数也都存在于它的命名空间下。本章讨论了下列BOM的组成部分。

    在使用框架时,每个框架都有自己的window对象以及所有原生构造函数及其他函数的副本。每个框架都保存在frames集合中,可以通过位置或通过名称来访问。

    有一些窗口指针,可以用来引用其他框架,包括父框架。

    Top对象始终指向最外围的框架,也就是整个浏览器窗口。

    Parent对象表示包含当前框架的框架,而self对象则回指window。

    使用location对象可以通过编程方式来访问浏览器的导航系统。设置相应的属性,可以逐段或整体的修改浏览器的URL。

    调用replace()方法可以导航到一个新的URL,同时该URL会替换掉浏览器历史记录当前显示的页面。

    Navigator对象提供了与浏览器有关的信息,到底提供哪些信息,很大程度上取决于用户的浏览器;不过,也有一些公共的属性(userAgent)存在于所有浏览器中。

    BOM中还有两个对象:screen和history,但它们的功能有限。Screen对象中保存着与客户端显示器有关的信息,这些信息一般只用于站点分析。History对象为访问浏览器的历史记录开了一个小缝隙,开发人员可以据此判断历史记录的数量,也可以在历史记录中向后或向前导航到任意页面。

    1. 客户端检测:

    客户端检测是javascript开发中最具有争议的一个话题。由于浏览器之间存在差别,通常需要根据不同浏览器的能力分别编写不同的代码。有不少客户端检测方法,但下列是最经常使用的。

    能力检测:在编写代码之前先检测特定浏览器的能力。例如,脚本在调用某个函数之前,可能要先检测该函数是否存在。这种检测方法将开发人员从考虑具体的浏览器类型和版本中解放出来,让他们把注意力集中到相应的能力是否存在上。能力检测无法精确的检测特定的浏览器版本。

    怪癖检测:怪癖实际上是浏览器实现中存在的bug,例如早期的webkit中就存在一个怪癖,即它会在for-in循环中返回被隐藏的属性。怪癖检测通常涉及到运行一小段代码,然后确定浏览器是否存在某个怪癖。由于怪癖检测与能力检测相比效率更低,因此应该只在某个怪癖会干扰脚本运行的情况下使用。怪癖检测无法精确的检测特定的浏览器和版本。

    用户代理检测:通过检测用户代理字符串来识别浏览器。用户代理字符串中包含大量与浏览器有关的信息,包括浏览器,平台,操作系统及浏览器版本。用户代理字符串有过一段相当长的发展历史,在此期间,浏览器提供商试图通过在用户代理字符串中添加一些欺骗性信息,欺骗网站相信自己的浏览器是另外一种浏览器。用户代理检测需要特殊的技巧,特别是要注意opera会隐瞒其用户代理字符串的情况。即便如此,通过用户代理字符串任然能够用检测出浏览器所用的呈现引擎以及所在的平台,包括移动设备和游戏系统。

    在决定使用哪种客户端检测方法时,一般应优先考虑使用能力检测,怪癖检测是确定应该如何处理代码的第二选择,而用户代理字符串检测则是客户端检测的最后一种方案,因为这种方法对用户代理字符串具有很强的依赖性。

    1. DOM:

    DOM是语言中立的API,用于访问和操作html和xml文档。DOM1级将html和xml文档形象的看作一个层次化的节点树,可以使用javascript来操作这个节点树,进而改进底层文档的外观和结构。

    DOM由各种节点构成,简要总结如下:

    最基本的节点类型是Node,用于抽象的表示文档中一个独立的部分;所有其他类型都继承自node。

    Document类型表示整个文档,是一组分层节点的根节点。在javascript中,document对象是document的一个实例。使用document对象,有很多种方式可以查询和取得节点。

    Element节点表示文档中的所有html或xml元素,可以用来操作这些元素的内容和特性。

    另外还有一些节点类型,分别表示文本内容,注释,文档类型,CDATA区域和文档片段。

    虽然DOM为访问文档结构提供了大量属性和方法,但浏览器还是针对常见用例扩展了DOM。

    对DOMzui通行的扩展,要数innerHTML属性了,通过这个属性,既可以取得某个元素中的HTML内容,也可以设置其HTML代码。这个属性最初由微软创造,现在已经可以在所有支持DOM的浏览器中使用。

    访问DOM的操作在多数情况下都很直观,不过在处理<script>和<style>元素时还是存在一些复杂性。由于这两个元素分别包含脚本信息和样式信息。因此浏览器通常会将他们与其他元素区别对待。

    这些区别导致了在针对这些元素使用innerHtml时,以及在创建新元素时的一些问题。

    理解DOM的关键,就是理解DOM对性能的影响。DOM操作往往是javascript程序中开销最大的部分,而因访问nodelist导致的问题为最多。Nodelist对象都是动态的,这就意味着每次访问nodelist对象,都会运行一次查询,有鉴于此,最好的办法就是尽量减少DOM操作。

    1. DOM2和DOM3:

    DOM2级规范定义了一些模块,用于增强DOM1级。“DOM2级核心”为不同的DOM类型引入了一些与XML命名空间有关的方法。这些变化只在使用XML或XHTML文档时才有用;对于HTML文档没有实际意义。除了与XML命名空间有关的方法外,“DOM2级核心”还定义了以编程方式创建document实例的方法,也支持了创建documentType对象。

    “DOM2级样式”模块主要针对操作元素的样式信息而开发,其特性简要总结如下。

    每个元素都有一个关联的style对象,可以用来确定和修改行内的样式。

    要确定某个元素的计算样式(包括应用给他的所有CSS规则),可以使用getComputedStyle()方法。

    IE不支持getComputedStyle()方法,但为所有元素都提供了能够返回相同信息currentStyle属性。

    可以通过document.stylesheets集合访问样式表。

    除IE之外的所有浏览器都支持针对样式表的这个接口,IE也为几乎所有相应的DOM功能提供了自己的一套属性和方法。

    “DOM2级遍历和范围”模块提供了与DOM结构交互的不同方法,简要总结如下。

    遍历即使用NodeIterator或treeWalker对DOM执行深度优先的遍历。

    NodeIterator是一个简单的接口,只允许以一个节点的步幅前后移动。而TreeWalker在提供了相同功能的同时,还支持在DOM结构的各个方向上移动,包括父节点,同辈节点和子节点等方向。

    范围是选择DOM结构中特定部分,然后再执行相应操作的一种手段。

    使用范围选区可以在删除文档中某些部分的同时,保持文档结构的格式良好,或者复制文档中的相应部分。

    IE不支持DOM2 级遍历和范围模块,但它提供了一个专有的文本范围对象,可以用来完成简单的基于文本的范围操作。

    1. 事件:

    事件是将javascript与网页联系在一起的主要方式。“DOM2级事件”中定义了常见的大多数事件,主要涉及如下5种事件类型。

    Ui事件:在操作页面上的元素时触发。

    鼠标事件:用户在操作鼠标时触发,主要包括mousedown,mouseup和click。

    键盘事件:用户在操作键盘时触发,主要包括keydown,keyup和keypress。

    HTML事件:当用户与页面或浏览器交互时触发,也可以由浏览器执行的操作触发。

    变动事件:直接与DOM文档相关,反映页面在生命周期内被修改的操作。

    虽然有些规范规定了一批基本的事件,但为满足开发人员更方便的实现用户交互的需要,许多浏览器还在实现规范的基础上,实现了一些专有事件。这些事件或者与用户交互有关,例如,mousewheel和contextmenu事件;或者涉及页面生命周期内的某个重要时刻,例如beforeunload和DOMContentLoaded事件,还有一些专有事件与特定的设备有关,例如移动safari浏览器支持的orientationchange事件,就是专属于iphone和ipod touch的。

    在使用事件时,需要考虑如下一些内存与性能方面的问题。

    有必要限制一个页面中事件处理程序的数量,数量太多会导致占用大量的内存,而且也会让用户感觉页面反应不够灵敏。

    建立在事件冒泡机制之上的事件委托技术,可以有效的减少事件处理程序的数量。

    建议在浏览器卸载页面之前移除页面中的所有事件处理程序。

    可以使用javascript在浏览器中模拟事件。“DOM2级事件”规范规定了模拟事件的方法,无论是模拟UI事件,鼠标事件,变动事件,还是模拟Html事件,都不是什么困难的事。此外,通过组合使用一些技术,还可以在某种程度上模拟键盘事件。IE同样支持事件模拟,只不过模拟的过程有些差异。

    事件时javascript中最重要的主题之一,深入理解事件的工作机制,以及它们对性能的影响至关重要。

    1. 表单脚本:

    虽然Html和web应用程序自诞生以来已经发生了天翻地覆的变化,但web表单相对却没有什么改变。使用javascript可以增强已有的表单字段,从而创造出新的功能,或者提升表单的易用性。为此,表单,表单字段都引入了相应的属性和方法,以便javascript使用。下面是本章介绍的几个概念。

    可以使用一些标准或非标准的方法选择文本框中的全部或部分文本。

    大多数浏览器都采用了firefox操作选择文本的方式,但IE仍然坚持自己的实现。

    在文本框的内容变化时,可以通过侦听键盘事件以及检测插入的字符,来允许或禁止用户输入某些字符。

    除opera之外的所有浏览器都支持剪贴板事件,包括copy,cut和paste。其他浏览器在实现剪贴板事件时也可以分为几种不同的情况。

    IE,chrome和safari允许通过javascript访问剪贴板中的数据,而firefox不允许这种访问方式。

    即使是IE,chrome和safari,它们各自的实现方式也不相同。

    Safari和chrome只允许在paste事件发生时读取剪贴板数据,而IE没有这个限制。

    Safari和chrome只允许在发生剪贴板事件时访问与剪贴板相关信息,而IE允许在任何时候访问相关信息。

    在文本框内容必须限制为某些特定字符的情况下,就可以利用剪贴板事件来屏蔽通过粘贴向文本框中插入内容的操作。

    选择框也是经常要通过javascript来控制的一个表单字段。由于有了DOM,对选择框的操作比以前要方便多了。添加选项,移除选项,将选项从一个选择框移动到另一个选择框,甚至对选项进行排序等操作,都可以使用标准的DOM技术来实现。

    富文本编辑功能是用一个包含空HTML文档的iframe元素来实现的。通过将空文档的designMode属性设置为“on”,就可以将该页面转换为可编辑状态,此时其表现如同字处理软件。在默认情况下,可以将字体加粗或者将文本转换为斜体,还可以使用剪贴板。Javascript通过使用execCommand()方法也可以实现相同的一些功能。另外,使用queryCommandEnabled(),queryCommandState()和queryCommandValue()方法则可以取得有关文本选区的信息。由于以这种方式构建的富文本编辑器并不是一个表单字段,因此在将其内容提交给服务器之前,必须将iframe中的HTML复制到一个表单字段中。

    1. 错误处理与调试:

    错误处理对于今天复杂的web应用程序开发而言至关重要。不能提前预测到可能发生的错误,不能提前采取恢复策略,可能导致较差的用户体验,最终引发用户强烈不满。多数浏览器在默认情况下都不会向用户报告错误,因此在开发和调试期间需要启动浏览器的错误报告功能。然而,在投入运行的产品代码中,则不应该再有诸如此类的错误报告出现。

    下面是几种避免浏览器相应javascript错误的方法。

    在可能发生错误的地方使用try-catch语句,这样你还有机会以适当的方式对错误给出响应,而不必沿用浏览器处理错误的机制。

    使用window.onerror事件处理程序,这种方式可以接受try-catch不能处理的所有的错误(仅限于IE和firefox)。

    另外,对于任何web应用程序都应该分析可能的错误来源,并制定处理错误的方案。

    首先,必须要明确什么是致命错误,什么是非致命错误。

    其次,再对代码进行分析,以判断最可能发生的错误。Javascript中发生错误的主要原因如下:

    类型转换

    未充分检测数据类型

    发送给服务器或从服务器接收的数据有错误。

    所有浏览器都有javascript调试器,有的是内置的,有的是以需要下载的扩展形式存在的。这些调试器都支持设置断点,控制代码执行及在运行时检测变量的值。

    1. Javascript与XML:

    Javascript对XML及其相关技术有相当大的支持,然而,由于缺乏规范,共同的功能却存在一些不同的实现。DOM2级提供了创建空XML文档的API,但没有涉及解析和序列化。既然规范没有对这些功能做出规定,浏览器提供商就各行其是,拿出了自己的实现方案。IE采取了下列方式。

    通过ActiveX对象来支持处理XML,而相同的对象也可以用来构建桌面应用程序。

    Windows携带了MSXML库,javascript能够访问这个库。

    这个库中包含对基本XML解析和序列化的支持,同时也支持XPath和XSLT等技术。

    Firefox为处理XML的解析和序列化,实现了两个新类型,简介如下:

    DOMParser类型比较简单,其对象可以将XML字符串解析为DOM文档。

    XMLSerializer类型执行相反的操作,即将DOM文档序列化为XML字符串。

    Firefox的实现方式成为了web开发中的事实标准。

    DOM3 级引入了一个针对XPath API的规范,该规范已经由firefox,safari,chrome和opera实现。这些API可以让javascript基于DOM文档运行任何XPath查询,并且能够返回任何数据的结果。

    IE以自己的方式实现了对XPath的支持,具体来说,就是两个方法:selectSingleNode()和selectNodes()。虽然与DOM3级API相比还存在诸多限制,但使用这两个方法仍然能够执行基本的XPath功能,即在DOM文档中查找节点或节点集合。

    与XML相关的最后一种技术是XSLT,没有公开发布的标准针对这种技术的功能定义相应的API。火狐为通过javascript处理转换建立了XSLTProcessor类型,此后不久,safari,chrome和opera也都实现了同样的类型。IE则针对XSLT提供了自己的方案,一个是简单的transformNode()方法,另一个是较为复杂的模板/处理器手段。

    1. E4X:

    EX4(ECMAScript for XML)是以ECMA-357标准的形式发布的对ECMAScript的一个扩展。E4X的目的是为操作XML数据提供与标准ECMAScript更相近的语法。E4X具有下列特征。

    与DOM不同,E4X只用了一个类型来表示XML中的各种节点。

    XML对象中封装了对所有节点都有用的数据和行为。为表现多个节点的集合,这个规范定义了XMLList类型。

    另外两个类型,Namespace和QName,分别表现命名空间和限定名。

    为便于查询XML结构,E4X还修改了标准的ECMAScript语法,修改的地方如下:

    使用两个点(..)表示要匹配所有后代元素,使用@字符表示应该返回一个或多个特性。

    星号字符(*)是一个通配符,可以匹配任意类型的节点。

    所有这些查询都可以通过一组执行相同操作的方法来实现。

    到2008年为止,火狐是唯一支持E4X的浏览器,尽管没有其他浏览器提供商承诺会实现E4X,但在服务器上,由于BEA Workshop for WebLogic的推动,E4X已经获得了不小的成功。

    1. Ajax与JSON

    Ajax是无须刷新页面就能够从服务器取得数据的一种方法。Ajax这个词是Asynchronous javascript+XML的简写。以前被称为远程脚本。关于ajax可以从以下几个方面来总结一下:

    负责ajax运作的核心对象是XMLHttpRequest(XHR)对象。

    XHR对象由微软最早在IE5中引入,用于通过javascript从服务器取得XML数据。

    在此之后,firefox,safari,chrome和opera都实现了相同的特性,使XHR成为了web的一个事实标准。

    虽然浏览器之间存在差异,但XHR对象的基本用法在不同浏览器之间还是相对规范的,因此可以放心的用在web开发当中。

    同源策略是对XHR的一个主要约束,它为通信设置了“相同的域,相同的端口,相同的协议”这一限制。试图访问上述限制之外的资源,都会引发安全错误,除非采用以下跨域解决方案。

    IE8率先尝试解决跨域通信问题,它引入了XDomainRequest(XDR)对象,作为请求外部资源的一种安全方式。

    Firefox也实现了自己的跨域XHR特性,但在firefox3发布之前又被删除了。

    展望未来,跨域请求对下一代web应用程序开发已经变得很重要了。

    虽然xml和javascript本身密不可分,但它并不受javascript开发人员的青睐。取而代之的新数据格式名叫JSON(javascript object notation),由javascript语法的子集构成,可以用来标记数据对象和数组。从理论上讲,XML能够表现的任何数据都可以使用JSON来表现。由于JSON借鉴了某些javascript语法,因此可以使用eval()函数将其高效的转换为对象。但使用eval()也带来了一定的安全隐患,为了避免XSS(cross site scripting)攻击,采取一些预防措施是十分必要的。

    各方面对ajax的鼓吹吸引了越来越多的开发人员学习javscript。

    1. 高级技巧:

    Javascript中的函数非常强大,因为他们是第一类对象。使用闭包和函数环境切换,还可以有很多使用函数的强大方法。例如:

    可以创建作用域安全的构造函数,确保在缺少new操作符时调用构造函数不会改变错误的环境对象。

    可以使用惰性载入函数,将任何代码分支推迟到第一次调用函数的时候。

    函数绑定可以让你创建始终在制定环境中运行的函数,同时函数柯里化可以让你创建已经填了某些参数的函数。

    将绑定和柯里化组合起来,就能够给你一种在任意环境中以任意参数执行任意函数的方法。

    Javascript中可以使用setTimeout()和setInterval()如下创建定时器。

    定时器代码是放在一个等待区域,直到时间间隔到了之后,此时将代码添加到javascript的处理队列中,等待下一次javascript进程空闲时被执行。

    每次一段代码执行结束之后,都会有一小段空闲时间进行其他浏览器处理。

    这种行为意味着,可以使用定时器将长时间运行的脚本切分为一小块一小块可以在以后运行的代码段。这种做法有助于web应用对用户交互有更积极的响应。

    Javascript中经常以事件的形式应用观察者模型。虽然事件常常和DOM一起使用,但是你也可以通过实现自定义事件在自己的代码中应用。使用自定义事件有助于将不同部分的代码相互之间解耦,让维护更加容易,并减少引入错误的机会。

    拖放对于桌面和web应用都是一个非常流行的用户界面范例,它能够让用户非常方便的以一种直观的方式重新排列或者配置东西。在javascript中可以使用鼠标事件和一些简单的计算来实现这种功能类型。将拖放行为和自定义事件结合起来可以创建一个可重复使用的框架,能应用于各种不同的情况下。

    1. 客户端存储:

    在客户端存储数据的能力对web应用而言越来越重要。本章涵盖了客户端存储的以下几个方面。

    以前,这种存储只能使用cookie完成,cookie是一小块可以客户端设置也可以在服务器端设置的信息,每次进行请求时都会传送它。

    Javascript提供了通过document.cookie访问cookie的功能。

    Cookie的限制使其可以存储少量数据,然而对于大量数据效率很低。

    IE提供了一种叫做用户数据的行为,可以应用到页面的某个元素上,它有以下特点。

    一旦应用后,该元素便可以从一个命名数据仓库中载入数据,然后可以通过getAttribute(),setAttribute()和removeAttribute()方法进行访问。

    数据必须明确使用save()方法保存到命名数据仓库中,以便能在会话之间持久化数据。

    DOM存储最初是在web应用1.0规格说明中定义的,后来被HTML5规格吸收了。

    DOM存储定义了两种用于存储数据的对象:sessionStorage和localStorage。前者严格用于在一个浏览器会话中存储数据,因为数据在浏览器关闭后立即删除;后者用于跨越会话持久化数据并给予跨域名安全策略。

    还有第三个对象globalStorgae,firefox中实现了它,因为Html5的早期版本定义过它。

    在后来的版本中,localStorage对象替代了globalStorgae,但功能非常相似。

    有了以上这些选项,就可以在客户端机器上使用javascript存储大量数据了。但你必需小心,不要存储敏感数据,因为数据缓存并不加密。

    1. 最佳实践:

    随着javascript开发的成熟,也出现了很多最佳实践,如可维护性,性能,部署。

    Javascript中的可维护性部分涉及到下面的代码约定。

    来自其他语言中的代码约定可以用于决定何时进行注释,以及如何进行缩进,不过javascript需要针对其松散类型的性质创造一些特殊的约定。

    由于javascript必须与html和css共存,所以让各自完全定义其自己的目的非常重要:javascript应该定义行为,html定义内容,css定义外观。

    这些职责的混淆会导致难以调试的错误和维护上的问题。

    随着web应用中的javscript数量的增加,性能变得更加重要,因此你需要牢记以下事项:

    Javascript执行所花费的时间直接影响到整个web页面的性能,所以其重要性是不能忽略的。

    针对基于c的语言的很多性能的建议也适用于javascript,如有关循环性能和使用switch语句替代if语句

    还有一个要记住的重要事情,即DOM交互开销很大,所以需要限制DOM操作的次数。

    流程的最后一步是部署,以下一些关键点

    为了协助部署,推荐设置一个可以将javascript合并为较少文件(理想情况下是1个)的构建过程。

    有了构建过程也可以对原代码自动运行额外的处理和过滤。例如,你可以运行javascript验证器来确保没有语法错误或者是代码没有潜在的问题。

    在部署前推荐使用压缩器将文件尽可能变小

    和http压缩一起使用可以让javascript文件尽可能小,因为对整体页面性能的影响也会最小。

    1. 未来的API:

    Web 浏览器中的javscript通过在已有的功能基础上引入新的API而不断增长。本章讨论了以下一些未来javascriptAPI方面的变更。

    选择器API是一个比较小的增加,唯一的目的是针对Html文档进行css查询。虽然它只定义了两个方法,但这个功能已经非常热门,且对于javascript库而言是必须的。未来,浏览器中的选择器API可以让库作者从自己重新创建css查询引擎中解放出来。

    Html5也许是自DOM被提议之后在javascript方面最令人兴奋的进步了。不同于之前的html规范版本,html5不仅仅定义了标记语言,还对BOM和DOM做了相关的变更,进而丰富了web应用的交互。诸如离线支持,修改历史对象以及客户端数据库,这些功能都让ajax应用变得更象本地桌面应用程序。

  • 相关阅读:
    innerHTML,outerHTML,innerText,outerText
    vue生命周期
    vue属性监听
    vue计算属性(通过计算得来的属性)
    express脚手架的安装,以及ejs的语法
    mongoose的基本操作方法
    vue的基本指令
    MongoDB
    五分钟让你拥有自己的聊天室
    带你了解世界最先进的手势识别技术 -- 微软,凌感,Leap...
  • 原文地址:https://www.cnblogs.com/ongoing/p/3096615.html
Copyright © 2020-2023  润新知