Wang's blog Wang's blog
首页
  • 前端文章

    • HTML教程
    • CSS
    • JavaScript
  • 前端框架

    • Vue
    • React
    • VuePress
    • Electron
  • 后端技术

    • Npm
    • Node
    • TypeScript
  • 编程规范

    • 规范
  • 我的笔记
  • Git
  • GitHub
  • VSCode
  • Mac工具
  • 数据库
  • Google
  • 服务器
  • Python爬虫
  • 前端教程
更多
收藏
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Wang Mings

跟随大神,成为大神!
首页
  • 前端文章

    • HTML教程
    • CSS
    • JavaScript
  • 前端框架

    • Vue
    • React
    • VuePress
    • Electron
  • 后端技术

    • Npm
    • Node
    • TypeScript
  • 编程规范

    • 规范
  • 我的笔记
  • Git
  • GitHub
  • VSCode
  • Mac工具
  • 数据库
  • Google
  • 服务器
  • Python爬虫
  • 前端教程
更多
收藏
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • Python爬虫

  • 前端教程

    • 团队规范

    • Project

    • JS

    • NodeJS

    • Vue

    • React

    • 效率工具

    • 读书笔记

      • 如何做到十倍阅读量
      • 《敏捷开发》读后总结
      • 《给大家看的设计书》笔记
      • 《Head First Design Patterns》
      • 《HTTP图解》
      • 《JavaScript高级程序设计》
        • [#](#javascript语言) JavaScript语言
          • [#](#标签的位置) 标签的位置
        • [#](#javascript数据类型) JavaScript数据类型
          • [#](#基本类型-引用类型) 基本类型/引用类型
          • [#](#函数) 函数
          • [#](#闭包) 闭包
          • [#](#解决方案) 解决方案
        • [#](#dom) DOM
          • [#](#dom级别) DOM级别
          • [#](#dom1级) DOM1级
          • [#](#dom2级) DOM2级
          • [#](#dom3级) DOM3级
          • [#](#其他dom标准) 其他DOM标准
          • [#](#xhtml命名空间支持) XHTML命名空间支持
          • [#](#节点层次) 节点层次
          • [#](#dom扩展) DOM扩展
          • [#](#事件) 事件
          • [#](#元素大小) 元素大小
          • [#](#_1-偏移量-offset) 1. 偏移量 offset
          • [#](#_2-客户区大小-client) 2. 客户区大小 client
          • [#](#_3-滚动大小-scroll) 3. 滚动大小 scroll
          • [#](#_4-确定元素大小) 4. 确定元素大小
        • [#](#html5-javascirpt-api) HTML5 JavaScirpt API
      • 读书精要
      • 程序员软技能指南
      • 《你不知道的JavaScript》
  • 教程
  • 前端教程
  • 读书笔记
wangmings
2022-07-19
目录

《JavaScript高级程序设计》

# # 《JavaScript高级程序设计》

javascript书籍中的经典,里面非常多细节解释的十分详细,而且有些晦涩难懂的概念,比如js面向对象、原型链、继承等,也能层层递进,深入浅出。忍不住赞叹:写的太棒了!

# # JavaScript语言

浏览器宿主中的JavaScript = ECMAScript + DOM + BOM。

Web浏览器只是ECMAScript实现的宿主环境之一。宿主环境不仅提供基本的ECMAScript实现,也会提供该语言的扩展(比如DOM/BOM),以便语言与环境之间对接交互。

DOM(文档对象模型)是针对XML但经过扩展用于HTML的应用程序编程接口。DOM把整个页面映射为一个多层节点结构。HTML的每个组成部分都是某种类型的节点,这些节点又包含着不同类型的数据。

  • ECMAScript 核心语言功能
    • 语法
    • 类型
    • 语句
    • 关键字
    • 保留字
    • 操作符
    • 对象
  • DOM(文档对象模型) 提供访问和操作网页内容的方法与接口
    • DOM视图 DOM节点(Node类型)
      • DOM查找
      • DOM操作
    • DOM事件
      • 事件捕获 document -> div
      • 事件冒泡 div -> document
    • DOM样式 CSS
  • BOM(浏览器对象模型) 与浏览器交互的方法与接口
    • window
      • history
      • document 唯一一个既属于BOM又属于DOM的对象
      • navigator
      • screen
      • location
    • cookie
    • XMLHttpRequest

js 是ECMAScript的具体实现。其定义了包含语法、关键字等,但不包括与浏览器相关的API。 js引擎不是独立运行的,它运行在宿主环境中。web宿主环境就是浏览器。

# # 标签的位置

  • 遇到<script>会暂停解析html + 浏览器遇到<body>标签才开始呈现内容,所以script应该放在body的最后

# # JavaScript数据类型

从属于ECMAScript规范定义。从技术角度讲,函数在ECMAScript中是对象,不是一种数据结构。(笔者注:所以js语言可以很好的实践函数式编程思想。关于函数式编程思想可以看笔者另外一篇笔记:函数式编程)

  • undefined
  • null
  • string
  • number
  • boolean
  • object

# # 基本类型/引用类型

JS变量松散,只是在特定时间用于保存特定值的一个名字。即不存在定义某个变量时必须保存何种数据类型

  • 基本类型
    • 复制直接拷贝副本
  • 引用类型
    • 复制的是指针,指针指向真实的内存(js是无法获取以及操作内存,只能通过指针代理)
    • 当覆盖新的值时,指针指向新对象
    // 以上解释了这个赋值问题
    var a = { name: 1 }
    var b = a // b和a指向同一个内存地址
    b = { aget: 1 } // b被指向新的内存地址,断开了与a的联系
    
1
2
3
4
5

# # 函数

函数是对象,函数名是指针(函数名代理着内存)

    // 以下都是等价的
    function add(a, b) {
        return a + b
    }
    
    var add = function(a, b) {
        return a + b
    }
    
    // 这种方式较为明显的诠释了实质:函数是对象,函数名是指针
    var add = new Function('a', 'b', 'a + b')
    
1
2
3
4
5
6
7
8
9
10
11
12

# # 闭包

指有权访问另一个函数作用域中的变量的函数。原理:

  • 后台执行环境中,闭包的作用域链包含自己的作用域、包含函数的作用域和全局作用域。
  • 通常函数的作用域及其所有变量都会在函数执行结束后被销毁。
  • 但是,当函数返回一个闭包时,这个函数的作用域将会一直在内存中保存,直到闭包不存在为止。
    function addThird(c) {
        var d = 10
        return function (a, b) {
            return a + b + c + d // 该函数能访问另外一个函数作用域的变量:c、d
        }
    }
    
    addThird(3)(1, 2) // 16
    
1
2
3
4
5
6
7
8
9

最典型需要闭包案例:

    // 连续打印5,而不是从1~4
    for (var i = 1; i < 5; i++) {
        setTimeout(function() { console.log(i) }, i * 1000)
    }
    
1
2
3
4
5

以上代码我们试图假设循环中的每个迭代在运行时都会给自己“捕获”一个i副本,但根据作用域的工作原理,实际情况是尽管循环中的五个函数是在各个迭代中分布定义的,但是这些函数都是被封闭在一个共享的全局作用域中,因此实际上只有一个i。

所以所有函数共享一个i的引用。

# # 解决方案

  1. 每次迭代都要一个闭包作用域
    for (var i = 1; i < 5; i++) {
        (function() {
            var j = i // 存储i副本,使得settimeout函数可以访问到外部作用域
            setTimeout(function() { console.log(j) }, j * 1000)
        })()
    }
    
    // 一般编码更常用这种方式
    for (var i = 1; i < 5; i++) {
        (function(j) {
            setTimeout(function() { console.log(j) }, j * 1000)
        })(i)
    }
    
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  1. 块作用域

块作用域本质上是将块变成一个可以被关闭的作用域。

    for (var i = 1; i < 5; i++) {
        let j = i // 块作用域
        setTimeout(function() { console.log(j) }, j * 1000)
    }
    
1
2
3
4
5

for循环头部的let声明还有一个特殊行为。这个行为指出变量在循环过程中不止被声明一次,每次迭代都会声明。随后的每个迭代都会使用上一个迭代结束时的值来初始化这个变量。

    for (let i = 1; i < 5; i++) {
        setTimeout(function() { console.log(i) }, i * 1000)
    }
    
1
2
3
4

# # DOM

DOM(文档对象模型),提供访问和操作网页内容的方法和接口,是针对HTML和XML文档的一个API(扩展XML)。DOM描绘了一个层次化的节点树。

借助DOM提供的API,开发人员可轻松自如的增删改查任何节点,即获得控制页面内容和结构的主动权。

# # DOM级别

# # DOM1级

1998年成为W3C标准,由两个模块组成:DOM Core 和DOM HTML。DOM Core规定如何映射基于XML的文档结构;DOM HTML模块则在DOM Core的基础上扩展,添加了对HTML的对象和方法(比如在对象上直接绑定事件el.onclick=function)。

# # DOM2级

DOM2目标宽泛了很多。主要有DOM2使得DOM1的DOM Core模块经过扩展支持XML命名空间。 同时引入了新的模块:

  • DOM 视图
  • DOM 事件(比如DOM2开始支持el.addEventListen('click', funcion)事件监听方式)
  • DOM 样式
  • DOM 遍历

# # DOM3级

目的同样是扩展DOM API,以满足操作XML的所有需求。

# # 其他DOM标准

除了DOM Core和DOM HTML接口之外,SVG语言(也是基于XML的)也发布了针对自己的DOM标准,使得SVG对象上可操作相对应的新的API。其他语言还包括MathML、SMIL

# # XHTML命名空间支持

HTML不支持XML命名空间,但XHTML支持XML命名空间。命名空间使用xmlns特性来指定。在混合使用两种语言的情况下,命名空间用处非常大。比如混合了XHTML和SVG语言的文档:

    <html xmlns="http://www.w3.org/1999/xhtml">
        <body>
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
                <rect x="0" y="0" widht="100" height="100"></rect>
            </svg>
        </body>
    </html>
    
1
2
3
4
5
6
7
8

通过设置命名空间,svg元素的所有子元素,以及这些元素的所有特性,都被认为属于http://www.w3.org/2000/svg命名空间。

由于引入了命名空间,所以DOM2级的Document类型新增了关于命名空间的方法。比如document.createElementNS(namespaceURI, tagName)

# # 节点层次

  • Node 所有节点都继承自Node类型(DOM1级定义)
    • 节点属性:nodeType/nodeName/nodeValue
    • 节点关系:firstChild/lastChild/childNodes/parentNode/nextSibling/previousSibling
    • 节点操作:appendChild()/replaceChild()/removeChild()/insertBefore()
  • Document 文档类型(nodeType=9)。表示整个HTML页面
    • window.document是其实例
    • document.documentElement指向<html>标签子元素,document.body指向<body>标签子元素。
    • 查找Node
      • getElementById()
      • getElementByName()
      • getElementByTagName()
    • 创建Node
      • createElement()
      • createTextNode()
  • Element 元素类型(nodeType=1),最常用类型
    • id/className
    • 属性操作:getAttribute()/setAttribute()/removeAttribute()
  • Text 文本类型

# # DOM扩展

  • 选择符API 从此不再需要getElementBy...
    • querySelector
    • querySelectorAll
    • matchsSelector
  • 元素遍历 弥补使用childNodes和firstChild属性时,行为不一致
    • childElementCount
    • firstElementChild
    • lastElementChild
    • previousElementSibling
    • nextElementSibling
  • HTML5 围绕如何使用新增标记,定义了大量JavaScirpt API
    • getElementByClassName
    • classList
      • add
      • contains
      • remove
      • toggle
    • 自定义数据属性 data-
    • postMessage
    • 拖放
      • draggable属性开启
      • dragstart/drag/dragend/dragenter/dragover/dragleave事件
      • dataTransfer对象传递数据
    • audio/video
    • hashchange/popstate
  • 专有扩展
    • children属性。对childNodes进行简化
    • el.contains(el)方法 某个节点是不是另外一个节点的后代
  • DOM2/DOM3
    • 样式
      • style属性 el.style.width
    • 范围(DOM2)
      • document.createRange()
    • 手动绑定/解除事件
    var myDiv = document.getElementByClassName('myDiv')
    myDiv.classList.add('current')
    myDiv.style.width = '100px'
    
1
2
3
4

# # 事件

  • 事件类型
    • UI
      • load
      • resize
      • scroll
    • 焦点
      • blur
      • focus
    • 鼠标与滚轮
      • click
      • dbclick
      • mousedown
      • mouseenter
      • ...
    • 键盘
      • keydown
      • keypress
      • keyup
    • 复合事件(虚拟键盘用到)
      • compositionstart
      • compositionupdate
      • compositionend
    • 变动事件
      • DOMNodeInserted
    • HTML5事件
      • hashchange
      • contextmenu
      • DOMContentLoaded(形成dom树之后就会触发)
      • beforeunload
      • readstatechange
    • 触摸与手势事件
      • 触摸:touchstart/touchmove/touchend/touchcancel
      • 手势:gesturestart/gesturechange/gestureend
    // DOM0事件处理
    var btn = document.getElementById('myBtn')
    btn.onclick = function() { ... }
    
1
2
3
4
    // DOM2事件处理,好处:可以添加多个事件处理程序
    var btn = document.getElementById('myBtn')
    btn.addEventListener('click', function() { ... }, false) // 最后为false,代表冒泡阶段捕获
    
1
2
3
4

# # 元素大小

元素的可见大小由高度、宽度决定,包括所有内边距、滚动条和边框大小(注意,不包括外边距)。

# # 1. 偏移量 offset

元素的偏移量。

注意offsetLef和offsetTop是相对于offsetParent元素。

  • offsetHeight
  • offsetWidth
  • offsetLeft
  • offsetTop

image

    // 案例:知道某个el元素在页面上的偏移量
    // 等同于el.getBoundingClientRect().top
    function getElementTop(el) {
        var actualTop = el.offsetTop
        var current = el.offsetParent
    
        while(current) {
            actualTop += current.offsetTop
            current = current.offsetParent
        }
        return actualTop
    }
    
1
2
3
4
5
6
7
8
9
10
11
12
13

# # 2. 客户区大小 client

指的是元素内容及内边距所占的空间大小(不包括边框和外边距)。

  • clientHeight
  • clientWidth

image

    // 案例:获取视口大小
    function getViewport(el) {
        if (document.compatMode == 'BackCompat') {
            // ie 7 以下版本
            return {
                width: document.body.clientWidth,
                height: document.body.clientHeight
            }
        } else {
            return {
                width: document.documentElement.clientWidth,
                height: document.documentElement.clientHeight
            }
        }
    }
    
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# # 3. 滚动大小 scroll

指的是包含滚动内容的的元素大小。

有些元素(如html),即使没有执行任何代码也能自动的添加滚动条,但另外一些元素(如div),则需要通过css的overflow属性设置才能滚动。

scrollHeight/scrollWidth主要用于确定元素内容的实际大小。例如带有垂直滚动条的页面总高度是document.documentElement.scrollHeight

  • scrollHeight
  • scrollWidth
  • scrollLeft
  • scrollTop

image

# # 4. 确定元素大小

浏览器为每个元素都提供了getBoundingClientRect()方法(注意该方法的兼容性)。这个方法会返回一个矩形对象,包含4个属性: left、top、bottom、right。

这些属性给出了元素在页面中相对于视口(页面坐标原点)的位置。

# # HTML5 JavaScirpt API

  • requestAnimationFrame
  • Page Visible API
    • IntersectionObserver
  • Geolocation API
  • File API
    • e.target.files
      • name
      • size
      • type
      • lastModifieDate
    • FileReader(可以想象为文件系统的XMLHttpRequest)
    • 对象URL createObjectURL
    • 结合拖放事件 e.dataTransfer.files
    • FormData
  • Web Worker
编辑 (opens new window)
《HTTP图解》
读书精要

← 《HTTP图解》 读书精要→

最近更新
01
theme-vdoing-blog博客静态编译问题
09-16
02
搜索引擎
07-19
03
友情链接
07-19
更多文章>
Theme by Vdoing | Copyright © 2019-2022 Evan Xu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式