JavaScript高级程序设计(红宝书) 阅读(1~2章)

前两章内容为:

第一章 什么是JavaScript、第二章 HTML中的JavaScript

声明:

内容为阅读红宝书的个人见解与总结,若理解有误,欢迎指出和批评。

第一章 什么是JavaScript

js最初是用来代替服务端处理输入验证。后续逐渐增加功能,到现在被公然为主流的编程语言,能实现复杂的计算与交互,包括闭包、匿名函数、甚至元编程(编写能够操作程序本身的代码。既能用来执行任务,又能当作值被其他程序处理和操作)

1.1 简单历史回顾

1995年网景公司开发了Mocha(改名为LiveScript) =>  和Sun公司合作,改名JavaScript(蹭了Java的热度) =>  微软发布JScript的JavaScript实现  => 1997年(老头开会)制定了标准ECMA-262 也就是ES标准  => 1998年后ES纳入ISO,大家以后都按这个标准完成JavaScript实现

1.2 JavaScript实现

js由三部分组成 ES(核心,语法标准)  DOM(文档对象模型)   BOM(浏览器对象模型)

1.2.1 ECMAScript

ES描述了这门语言的语法、类型、语句、关键字、保留字、操作符、全局对象

1.ES版本

关于ES的版本,主要以ES6为分界,2015年6月发布的ES6,包含了最重要的一批增强特性,ES6正式支持了类、模块、迭代器、生成器、箭头函数、代理、反射、期约和众多新数据类型。2017年发布的ES8,增加了异步函数async/await 以及其他API与字符串填充方法。

(声明:关于其他版本,由于本人认知有限,对其他的修订和新增并不了解。如果想深入细究,请查阅原书或自己搜索网络信息。本文章仅是个人自学复习使用。) 

2.符合性

符合性就是,必须支持ES中的所有“类型、值、对象、属性、函数,以及程序语法、语义”还要支持Unicode字符标准、增加ES中媒体记得额外(类、值、对象、属性、函数)、还要支持允许修改和扩展内置的正则表达式特性。

3.浏览器对ES的支持

重点注意IE浏览器,不过现在也不怎么需要担心了。

1.2.2 DOM

简单来说DOM就是一个API,用来在HTML中使用扩展的XML。

DOM将代码表示为一组分层节点(树),开发者通过DOM树可以随心所欲控制网页的内容和结构。使用DOM API,轻松删除、添加、替换、修改节点。

举例,如下代码会被DOM表示为分层节点。

<html> 
     <head> 
         <title>Sample Page</title> 
     </head> 
     <body> 
         <p> Hello World!</p> 
     </body> 
</html>

1.2.3 BOM

BOM主要是支持访问和操作浏览器窗口。HTML5(H5)之前没有标准,后面规范化了。
总的来说BOM主要针对浏览器窗口和子窗口(frame),不过通常将特定于浏览器的拓展都算在BOM上了,比如(弹出新窗口;缩放、移动和关闭浏览器窗口;navigator对象提供浏览器信息;location对象:提供浏览器加载页面信息;screen对象,提供屏幕分辨率信息;performance对象,提供浏览器内存占用、导航行为、时间统计的信息;以及cookie的支持;其他自定义属性比如XMLHttpRequest和IE的ActiveXObject)

1.3 JavaScript版本

1.4 小结

JavaScript是一门用来和网页交互的脚本语言,包含三部分。

1.ECMAScript 提供核心功能

2.DOM 提供与网页交互的方法和接口 

3.BOM提供和浏览器交互的方法和接口



第二章 HTML中的JavaScript

本章主要内容是

1.使用<script>元素 ;2.行内脚本和外部脚本的比较 

3.文档模式对js的影响;4.js不可用时的用户体验

2.1 <script>元素

js插入到HTML的主要方法就是直接在HTML文档中使用<script>元素,有关<script>元素由以下八个属性。

async表示应该立即开始下载脚本,但不会阻止其他页面动作,比如下载资源或等待其他脚本加载。只对外部脚本(不同服务器上)文件有效。(执行的时机不确定,不一定按顺序来)

defer: 表示脚本可以延迟到文档完全被解析和显示之后再执行。只对外部脚本有效(IE7及以前,对行内脚本也可以指定)。(执行的时机确定,按顺序)

src: 表示包含要执行的代码的外部文件(有src属性,<script>中的内容不生效</script>)

crossorigin:配置相关请求的CORS(跨域资源共享)设置。默认不使用CORS。(CORS的解决很重要,目前我还没见过使用这个属性的情况)

type:代替了language属性,如果这个值是module,则代表代码被当成ES6模块(模块是指一个独立的单元,通常用于封装相关的代码、数据和功能),只有这时才能出现import和export关键字。

PS:面向对象编程的三大特性:封装、继承、多态。模块化在 JavaScript 中确实体现了面向对象编程 (OOP) 的一些特性。但js不只是面向对象。

charset:使用src属性指定的代码字符集。(不重要)、integrity(不重要)、language(废弃了)

使用<script>的方式有两种:直接在网页中嵌入、以及通过它在网页中包含外部的js文件

方式一:代码直接放在script元素中就行。

<script>
    function sayHi() {
        console.log("Hi!")
    }
    sayHi() // 控制台打印 Hi
</script>

注意代码中不要出现</script> 不然解析时浏览器会报错,它会以外是script结束了。想要解决这个问题,我们得用转义字符“\”转义一下

<script>
    function sayScript() {
        console.log("</script>") // 直接报错了,以为结束了
    }
    sayScript() 

    //正确写法 配合转义字符\
    function sayScript() {
        console.log("<\/script>") // 打印</script>
    }
    sayScript() 
</script>

方法二:使用外部文件中的js,必须使用src属性,这个属性四个URL,指向js文件

<script src="example.js"></script>

外部的example.js

function sayHi(){
    console.log("Hi")
}

<script>属性很强大,可以使用外部域的js文件而且不受同源策略影响,有时也用来解决跨域问题,正因为功能的强大,所以使用时要确保引用文件的安全性。

关于<script>的执行顺序,不管包含什么代码,浏览器都会按照<script>在页面出现的顺序依次执行,前提是没使用defer和async属性,第二个<script>必须在第一个<script>元素的代码解释完才开始解释!

2.1.1 标签位置

记住现在主流就是放在</body>前,也就是<body>标签的最末尾。原因是:将<script>放在前面,需要先下载js代码、解析和解释完毕后才渲染页面,这会导致页面渲染有明显延迟。提升体验。

2.1.2 推迟执行脚本

前面提及到的defer属性,这个属性表示脚本在执行时不会改变页面的结构。也就是说,脚本会被延迟到整个页面都解析完毕后再执行。<script>元素上设置defer属性,相对于告诉浏览器,立即下载,但延迟执行。如果出现连续两个<script>中都设置defer属性,理论上他们会按照顺序严格执行(都在DOMContentLoaded事件前执行),不过在实际中,不一定会按顺序或在DOMContentLoaded事件前执行。所以建议只包含一个带defer属性的标本。并且注意,defer只对外部脚本文件有效。

DOMContentLoaded 是指在 HTML 文档加载并解析完成后触发的事件,表示文档中的所有 DOM 元素已经被加载,但外部资源(如图片、样式表、脚本等)可能还没有完成加载。

2.1.3 异步执行脚本

<script>标签中的async值,与前面的defer类似,二者也都只适用于外部脚本,都会告诉浏览器立即开始下载。不过标记了async的脚本并不能保证按照次序执行,标记了async就等于告诉浏览器,不必等到脚本下载和执行完再加载页面,也不必等这个异步脚本下载和执行后再去加载其他脚本,(浏览器你自己继续工作,我自己加载完就执行不用管我)。也因为如此,异步脚本中不应该在加载期间修改DOM。(如果异步脚本中有DOM操作,那么就可能导致页面回流与重绘

页面回流reflow:浏览器重新计算并更新页面布局的过程。

重绘repaint:浏览器根据新的样式信息重新绘制页面。

2.1.4 动态加载脚本

除了<script>标签,我们还有别的方式加载脚本。因为js是可以使用DOM API的,所以我们可以向DOM中动态添加<script>元素。

let newscript = document.createElement('script') //创建一个<script>标签
newscript.src = 'example.js'  // 传入创建标签的src
document.head.appendChild(newscript) // 把创建出来带有src属性的新标签,加在<head>末尾

这种方式默认都是异步加载,相当于添加了async,虽然浏览器都支持createElement()方法,但是不是所有浏览器都支持async属性,所有如果要变成同步加载,还需要设置 newscript.async=false;以这种方式来获取资源,预加载器是不可见的,这会严重影响他们在资源获取队列中的优先级(不能预先加载)。要想让预加载器知道这些动态请求的存在,可以在文档头部就显示声明它们

<link rel="preload" href="example.js">

注意,此处link预先下载example.js文件,告诉浏览器后面会用到。此处还没引用,而是等到后续动态创建script时,从缓存中可以直接取example.js 这样更快一些。只是改变了浏览器的资源获取队列,而不是改变了脚本加载顺序。

2.2 行内代码与外部文件

关于行内代码和外部文件两种形式,实践中最好是尽可能将js代码放在外部文件中。理由如下

1.可维护性。js代码如果分散到很多html文件页面,会导致维护困难。而用一个目录来保存所有js文件,更容易维护,这样开发者就可以独立于页面来编辑代码。

2.缓存。浏览器会根据特定的设置来缓存所有外部链接的js文件。这就意味着,两个页面用同一个文件,之u需要下载一次。这会使得页面加载更快

3.适应未来。

2.3 文档模式

(现阶段没有了解)

2.4 <noscript>元素

这是针对早期浏览器不支持js,做出的优雅降级方案。即使用<noscript>元素代替内容。若浏览器不支持脚本、浏览器对脚本的支持被关闭。则<noscript>中的内容会被渲染。

2.5 小结

js是通过<script>元素插入到HTML页面中的。该元素既可以将js代码嵌入到html页面,也可以引用外部文件的js。本章总结如下

1.要包含外部js文件,需要给src属性设置文件的URL。文件可以和网页可以不在同一服务器。

2.所有<script>元素会按照出现次序被解释。在不适用defer和async属性的情况下。

3.对于不推迟执行的脚本,浏览器必须解释完<script>中的代码,才能继续渲染页面其他部分。因此我们常将<script>元素放在页面末尾,也就是</body>前

4.使用defer属性,可以将脚本推迟到文档渲染完毕后在执行(DomContentLoaded),设置defer的代码会按次序执行。

5.使用async属性表示脚本不需要等待其他脚本,也不阻塞文档渲染,即异步加载。异步加载不能保证按出现次序执行。

6.还可以使用操作DOM API的方法,动态加载js文件,不过会在js文件加载优先级上不利,建议搭配link标签,预加载js文件。

7.可以使用<noscript>元素,对不支持js的浏览器优雅降级。

  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值