JS高设

JavaScript简介

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

  • ECMAScript,由ECMA-262定义,提供核心语言功能
  • DOM 文档对象模型,提供访问和操作网页内容的方法和接口
  • BOM 浏览器对象模型,提供与浏览器交互的方法和接口

在HTML中使用JavaScript

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

  • 在包含外部JavaScript文件时,必须将src属性设置为指向相应文件的URL。而这文件既可以是与包含它的页面位于同一个服务器上的文件,也可以是其他任何域中的文件。
  • 所有<script>元素都会按照他们在页面中出现的先后顺序依次被解析。在不使用defer和sync属性的情况下,只有在解析完前面<script>元素中的代码之后,才会开始解析后面<script>元素中的代码
  • 由于浏览器会先解析完不适用defer属性的<script>元素中的代码,然后再解析后面的内容,所以一般应该吧<script>元素放在页面最后面,即主要内容后面,</body>标签前面。
  • 使用defer属性可以让脚本在文档完全呈现之后再执行。延迟脚本总是按照指定它们的顺序执行。
  • 使用async属性可以表示当前脚本不必等待其他脚本,也不必阻塞文档呈现。不能保证一部脚本按照它们在页面中出现的顺序执行。
    另外,使用<noscript>元素可以指定在不支持脚本的浏览器中显示的替代内容。但在启用了脚本的情况下,浏览器不会显示<noscript>元素中的任何内容

基本概念

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

  • ECMAScript中的基本数据类型包括Undefined、Null、Boolean、Number、String。
  • 与其它语言不同,ECMAScript没有为整数和浮点数指分别定义不同的数据类型、Number类可用于表示所有数值。
  • ECMAScript中也有一种复杂的数据类型,即Object类型,该类型是这门语言中所有对象的基础类型。
  • 严格模式为这门语言中容易出错的地方施加了限制。
  • ECMAScript提供了很多与C及其他类C语言中相同的基本操作符、包括算术操作符、布尔操作符、关系操作符、相等操作符、复制操作符。
  • ECMAScript从其他语言中借鉴了很多流控制语句,例如if语句、for语句和switch语句等。ECMAScript中的函数与其他语言中的函数有诸多不同之处、
  • 无需指定函数的返回值,因为任何ECMAScript函数都可以再任何时候返回任何值。
  • 实际上,未指定返回值的函数返回的是一个特殊的Underfined值。
  • ECMAScript中也没有函数签名的概念,因为其函数参数是以一个包含灵活多个值的数组的形式传递的。
  • 可以向ECMAScript函数残敌任意数量的参数,并且可以通过arguements对象来访问这些参数。
  • 由于不存在函数签名的特性,ECMAScript函数可以重载。

变量、作用域、和内存问题

JavaScript变量可以用来保存两种类型的值:基本类型值和引用类型值。基本类型的源自以下五种基本数据类型:Underfined、Null、Boolean、Number、String。它们具有以下特点:

  • 基本类型值在内存中占据固定大小的空间,因此被保存在栈内存中;
  • 从一个变量向另一个变量复制基本类型的值,会创建这个值的一个副本;
  • 引用类型的值是对象,保存在堆内存中;
  • 包含引用类型值的变量实际上包含的并不是对象本身,而是一个指向该对象的指针;
  • 从一个前两向另一个变量复制引用类型的值,复制的其实是指针,因此两个变量最终都指向同一个对象
  • 确定一个值是哪种基本诶性可以使用typeof操作符,而确定一个值是哪种引用类型可以使用instanceof操作符、

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

  • 执行环境有全局执行环境(也成为全局环境)和函数执行环境之分;
  • 每次进入一个新执行环境,都会创建一个用于搜索变量和函数的作用域链;
  • 函数的局部环境不仅有权访问函数作用域中的变量,而且有权访问其包含(父)环境,乃至全局环境;
  • 全局环境只能访问在全局环境中定义的变量和函数,而不能直接访问局部环境中的任何数据;
  • 变量的执行环境有助于确定应该何时释放内存;
    JavaScript是一门具有自动垃圾收集机制的编程语言。开发人员不必关心内存分配和回收问题:
  • 离开作用域的值将被自动标记为可以回收,因此将在垃圾收集期间被删除;
  • “标记清除”是目前主流的垃圾回收算法,这种算法的思想,是给当前不使用的值加上标记,然后再回收其内存;
  • 另一种垃圾收集算法是“引用计数”,这种算法的思想是跟踪记录所有值被引用的次数。当代码中存在循环引用现象时,“引用计数”算法就会导致问题。不推荐使用了;
  • 解除变量的引用不仅有助于消除循环引用现象,而且对垃圾收集也有好处。为了确保有效的回收内存,应该及时解除不再使用的全局对象、全局对象属性以及循环引用变量的引用。

引用类型

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

  • 引用类型与传统面向对象程序设计中的类相似,但实现不同;
  • Object是一个基础类型,其他所有类型都从Object继承了基本的行为;
  • Array类型是已组织的有序列表,同时还提供了操作和转换这些值的功能;
  • Date类型提供了有关日期和时间的信息,包括当前日期和时间以及相关的计算功能;
  • RegExp类型是ECMAScript支持正则表达式的一个借口,提供了最基本的和一些高级的正则表达式功能;

函数实际上是Function类型的实例,因此函数也是对象;而这一点正式JavaScript最有特色的地方,由于函数是对象,所以函数也拥有方法,可以用来增强其行为。
因为有了基本包装类型,所以JavaScript中的基本类型值可以被当做对象来访问。三种基本包装类型分别是:Boolean、Number、String,以下是他们共同的特征:

  • 每个包装类型都映射到同名的基本类型;
  • 在读取模式下访问基本类型值时,就会创建对应的基本包装类型的一个对象,从而方便了数据操作;
  • 操作基本类型值的语句一经执行完毕,就会立即销毁新创建的包装对象
    在所有代码执行之前,作用域中就已经存在两个内置对象:Global和Math。在大多数ECMAScript视线中都不能直接访问Global对象;不过,Web服务器实现了承担该角色的Window对象。全局变量和函数都是Global对象的属性。Math对象提供了很多属性和方法,用于辅助完成复杂的数学计算任务;

面对对象的程序设计

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

  • 工厂模式,使用简单的函数创建对象,为对象添加属性和方法,然后返回对象,这个模式后来被构造函数模式所取代。
  • 构造函数模式,可以创建自定义引用类型,可以向创建内置对象实例一样使用new操作符。不过,构造函数模式也有缺点,即他的每个成员都无法得到复用,包括函数。由于函数可以不局限于任何对象(即与对象有松散耦合的特点)因此没有理由不在多个对象间共享函数。
  • 原型模式,使用构造函数的prototype属性来指定那些应该共享的属性和方法。组合使用构造函数模式和原型模式时,使用构造函数定义实例属性,而使用原型定义共享的函数和方法。

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

  • 原型式继承,可以再不必预先定义构造函数的情况下实现继承,其本质是执行对给定对象的浅复制。而复制得到的副本还可以得到进一步改造。
  • 寄生式继承,与原型式继承非常相似,也是基于某对象或某些信息创建一个对象,然后增强对象,最后返回对象。为了解决组合继承模式由于多次调用超类型构造函数而导致的低效率问题,可以将这个模式和组合继承一起使用。
  • 寄生组合式继承,☆☆☆☆☆推荐的继承方法!!

函数表达式

在JavaScript编程中,函数表达式是一种非常有用的技术。使用函数表达式可以无需对函数进行命名从而实现动态编程。匿名函数:拉姆达函数,是一种使用JavaScript函数的强大方式。以下总结了函数表达式的特点:

  • 函数表达式不同于函数声明。函数声明要求有名字,但函数表达式不需要。没有名字的函数表达式也叫做匿名函数。
  • 在无法确定如何引用函数的情况下,递归函数就会变得很复杂。
  • 递归函数应该始终使用arguements.callee来递归的调用自身,不要使用函数名——因为函数名能产生变化。

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

  • 在后台执行环境中,闭包的作用域链包含着他自己的作用域、包含函数的作用域和全局作用域。
  • 通常,函数的作用域及其所有变量都会在函数执行结束后被销毁。
  • 但是,当函数返回了一个闭包时,这个函数的作用域将会一直在内存中保存到闭包不存在为止。
    使用闭包可以再JavaScript中模仿块级作用域(JavaScript本身没有块级作用域的概念),要点如下:
  • 创建比立即调用一个函数,这样既可以执行其中的代码,又不会再内存中留下对该函数的引用。
  • 结果就是函数内部的所有变量都会被立即销毁——除非将某些变量赋值给了包含作用域(外部作用域)中的变量

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

  • 即使JavaScript中没有正式的私有对象属性的概念,但可以使用闭包来实现公有方法,而通过公有方法可以访问在包含作用域中定义的变量。
  • 有权访问私有变量的公有方法叫做特权方法。
  • 可以使用构造函数模式、原型模式来实现自定义类型的特权方法,也可以使用模块模式、增强的模块模式来实现单例的特权方法

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

BOM

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

  • 在使用框架时,每个框架都有自己的window对象以及所有原生构造函数以及其他函数的副本。每个框架都保存在frames集合中,可以通过位置或通过名称来访问。
  • 有一些窗口指针,可以用来引用其他框架,包括父框架。
  • top对象时钟指向最外围的框架
  • parent对象表示包含当前框架的框架,也就是整个浏览器窗口
  • 使用location对象可以通过变成方式来访问浏览器的导航系统。设置相应的属性,可以逐段或整体性的修改浏览器的URL
  • 调用replace()方法可以导航到一个新的URL,同时该URL会替换浏览器历史记录中当前显示的页面
  • navigator对象提供了与浏览器相关的信息。到底提供哪些信息,很大程度上取决于用户的浏览器,不过也有一些公共的属性(如UserAgent)存在于所有浏览器中。

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

DOM

DOM是语言中立的API,用于访问和操作HTML和XML文档。DOM1级将HTML和XML文档形象的看作一个层次化的节点树,可以使用JavaScript来操作这个节点树,进而改变底层文档的外观和结构,DOM由各种节点构成,简要的说:

  • 最基本的节点类型是Node,用于抽象的表示文档中一个独立的部分;所有其他类型都继承自Node。
  • Document类型表示整个文档,是一组分层节点的根节点。在JavaScript中,document对象是Document的一个实例。使用document对象,有很多方式可以查询和取得节点。
  • Element节点表示文档中的所有HTML或XML元素,可以用来操作这些元素的内容和特性。
  • 另外还有一些节点类型,分别表示文本内容,注释,文档类型,CDATA区域和文档片段。

访问DOM的操作在多数情况下都很直观,不过在处理<script>和<style>元素时还是存在一些复杂性。由于这两个元素分别包含脚本和样式信息,因此浏览器通常会将它们与其他元素区别对待。这些区别导致了在针对这些元素使用innerHTML时,以及在创建新元素时的一些问题。
理解DOM的关键,就是理解DOM对性能的影响。DOM操作往往是JavaScript程序中开销最大的部分,而因访问NodeList导致的问题为最多。NodeList对象都是“动态的”,这就意味着每次访问NodeList对象,都会运行一次查询。有鉴于此,最好的办法就是尽量减少DOM操作

DOM扩展

虽然DOM为与XML及HTML文档交互制定了一系列核心API,但仍然有几个规范对标准的DOM进行了扩展。这些扩展中有很多原来是浏览器专有的,但后来成为了事实标准,于是其他浏览器也都提供了相同的实现。

  • Selectors API定义了2个方法,让开发人员能够基于CSS选择符从DOM中取得元素,这2个方法是querySelector()和querySelectAll()
  • Element Traversal,为DOM元素定义了额外的属性,让开发人员能够更方便的从一个元素跳到另外一个元素。之所以会出现这种拓展,是因为浏览器处理DOM元素间
  • HTML5,为标准的DOM定义了很多扩展功能。其中包括在innerHTML属性这样的事实标准基础上提供的标准定义,以及为管理焦点,设置字符集,滚动页面而规定的扩展API

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结构中特定部分,然后再执行相应操作的一本手段。
  • 使用范围选取可以在删除文档中某些部分的同时、保持文档结构的格式良好,或者复制文档中的相应部分

事件

时间

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容