您的位置:首页 > Web前端 > JavaScript

JS红宝书学习记录(三)

2020-07-28 20:48 141 查看

js红宝书学习记录7-12

argument.callee
,一个指向正在执行的函数的指针,解决js递归对函数名的耦合。

闭包

之前在网上看过很多相关的解释,虽然能看懂,但就是有一种传声筒传达的感觉,越传越失真的感觉,下面来看原汁原味的。

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

本质:函数;特点:有权访问其他作用域的变量。

原理:

  • 闭包的作用域通常包含着它自己的作用域,包含函数的作用域以及全局作用域。
  • 通常函数作用域及其所有变量都会在函数执行时销毁
  • 但是,当函数返回了一个闭包时,这个函数的作用域会一直在内存中保存到闭包不存在为止。

来一道经典闭包题:

function fun(n,o){
console.log(o);
return {
fun:function(m){
return fun(m,n);
} // 可看到返回的是对象,里面再返回了一个fun函数
}
}
var a = fun(0);a.fun(1);a.fun(2);a.fun(3);
=> undefined // 由于传参的时候没有传o,打印时就是undefined
=> 0 // a现在是一个对象,拥有fun属性。执行a.fun函数时=>返回一个fun(1,0)(此时在作用域内找不到fun和n往上一个作用域找即最开始的fun和入参n=0),函数执行后打印了o值也就是0
=> 0 // 同理,fun(2,0),打印0
=> 0 // 同理,fun(3,0),打印0
var b = fun(0).fun(1).fun(2).fun(3);
=> undefined // 第一个fun(0),没传o,打印undefined
=> 0 // 第二个fun(1),执行fun(1,0),打印第二参数0。因为后面还有链式调用,注意下此时fun(1,0)返回了对象{fun:m=>fun(m,1)}
=> 1 // {fun:m=>fun(m,1)},调用.fun(2),即fun(2,1),打印1。此时fun(2,1)返回了对象{fun:m=>fun(m,2)}
=> 2 // {fun:m=>fun(m,2)},调用.fun(3),即fun(3,2),打印2.
var c = fun(0).fun(1); c.fun(2);c.fun(3);
=> undefined // 第一个fun(0),没传o,打印undefined
=> 0 // 第二个fun(1),执行fun(1,0),打印第二参数0。此时c就是对象{fun:m=>fun(m,1)}
=> 1 // {fun:m=>fun(m,1)},调用.fun(2),即fun(2,1),打印1。
=> 1 // {fun:m=>fun(m,1)},调用.fun(3),即fun(3,1),打印1。

上述题目的重点就是理解n值的闭包。

BOM对象

widow对象

window指向当前框架,top指向浏览器窗口的框架(最外层),parent指向指向当前框架的直接上层框架。在没有框架的情况下,

window==top==parent

window.open()方法,四个参数:

  1. url

  2. 窗口目标(比如topFrame,如果有该窗口就在加载在这,否则新建新窗口“topFrame”)

    特殊名称:

      _blank - URL加载到一个新的窗口。这是默认
    • _parent - URL加载到父框架
    • _self - URL替换当前框架
    • _top - URL替换当前顶层即浏览器框架
  3. 特性字符串

  4. 表示新页面是否取代浏览器历史记录中记载当前页面的布尔值。

location对象

属性:

  • hash:#后面的字符串
  • host:服务器名称+端口
  • hostname: 服务器名称
  • href: 完整url,==loaction.toString()
  • pathname:目录和文件名
  • port:端口
  • protocol:协议
  • search:?开头的查询字符串

可以看到其实核心就是url,其余属性都是为了方便开发者使用而帮我们解析出来的。

方法:

  • assign:立即打开url并生成历史记录
  • replace:打开url但不生成历史记录
  • reload:重加载,reload(true)强制刷新

history对象

方法:

  • go(num:a)a类似数组序号,跳转历史记录 back():向前
  • forward():向后

DOM对象

NODE类型

12类型:

  1. ELEMENT_NODE :元素节点

    属性:id,title,lang,dir,className

    可以通过document.createElement创建

  2. ATTRIBUTE_NODE

  3. TEXT_NODE :文本节点

    可以通过document.createTextNode()创建,HTML编码的有效方式。

  4. CDTA_SECTION_NODE:基于XML的文档,表示CDATA区域

  5. ENTITY_REFERENCE_NODE

  6. ENTITY_NODE

  7. PROCESSING_INSRUCTION_NODE:处理指令

  8. COMMENT_NODE:注释节点,如 <! --></–>

  9. DOCUMENT_NODE:文档节点

    属性:documentElement(访问子元素),body,title,URL,domain,referrer

    方法:getElementById(),getElementByTagName(),getElementByName(),write()

  10. DOCUMENT_TYPE_NODE:文档注释,如”<!DOCTYPE>“

  11. DOCUMENT_FRAGMENT_NODE:文档片段,轻量级文档,可以包含和控制节点,但不占用资源。(可以当成仓库使用,保存未来可能使用的节点)

  12. NOTATION_NODE

书中出现的常用节点类型:

节点类型 nodeType nodeName nodeValue parentNode childNodes(数字为Type值,?:0-1次)
DOCUMENT 9 #document null null 10?,1?,7,8
ELEMENT 1 标签名(tagname) null Document或Element 1,3,8,7,4,5
TEXT 3 #text 包含的文本(data) Element
COMMENT 8 #comment 注释的内容 Document或Element
CDTA_SECTION 4 #cdata-section CDATA区域的内容 Document或Element
DOCUMENT_TYPE 10 doctype的名称 null Document
DOCUMENT_FRAGMENT 11 #document-fragement null null 1,7,8,3,4,5
ATTRIBUTE 2 特性的名称 特性的值 null HTML无,XML可能是TEXT或EntityReference

一直有个疑惑,nodeList和HTMLCollection的区别?参考这个https://www.zhihu.com/question/31576889

nameNodeMap:

参考MDN的解释 https://developer.mozilla.org/zh-CN/docs/Web/API/NamedNodeMap

它表示属性节点

Attr
对象的集合

同时要理解

nodeList
HTMLCollection
nameNodeMap
三者都是动态的,访问这三个属性都会去查询非常消耗时间。

参考了这个 http://tiantang-tt.github.io/2016/06/27/HTMLCollection-NodeList-NamedNodeMap/

三者都是一个动态的类数组,每当文档发生变化时,他们都会更新。他们将始终保持这最新、最准确的消息。

通过getElemetnsByTagName获取的是一个HTMLCollection。element.childNodes获取到的是一个NodeList,是Node(节点)的 集合,可能同时包括element节点其他节点。element.attributes获取的则是一个特性Attribute集合,而集合中的每一个元素,都是Attr类型的对象。Attr对象有三个属性,name、value和specified。但是在日常应用中,一般会应用getAttribute()、setAttribute()和romoveAttribute()来操作特性,不需要直接访问特性对象。

文章中还提到querySelectorALl返回的虽然也是NodeList,但它却是一个快照,静态的!!

节点操作:

注意使用这些方法时确保parent的是拥有子节点的节点类型

  • appendChild:末尾添加节点
  • insertBefore(要插入的节点,参照节点)如果参照是null则==appendChild
  • replaceChild(要插入的节点,替换节点)
  • removeChild:移除指定节点

所有节点都有的:

cloneNode:深复制节点

normalize:删除空文本节点,合并相邻文本节点

在元素节点的子节点处解析下面的文档:

<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
  • IE解析为3个element子节点
  • 其他浏览器为3个li元素节点和4个文本节点

DOM扩展

来到更常见的操作节点的API了。(接近jQuery的用法)

选择符

querySelector():返回第一个匹配的元素

querySelectorAll():返回所有匹配的元素组成的NodeList对象

matchesSelector():检查节点是否匹配

H5

getElementByClassName()

classList属性:DOMTokenList的实例,拥有add,contains,remove,toggle,item等方法。分割class,方便我们设置class字符串。

document.activeElement:始终保存获得焦点的元素

document.readState: ‘complete’ or ‘loading’,表示加载文档的状态

document.head

document.charset

为元素添加data-前缀,就可以通过dataset属性来访问自定义属性

innerHTML

outerHTML:区别在于outer会把当前节点整个替换

insertAdjacentHTML(插入位置,插入文本)

scrollIntoView

DOM2和DOM3

Node

包含localName(节点名称),namespaceURI(命名空间URI或null),prefix:命名空间前缀。DOM3增加了些检测方法

dcument,elemen,NameNodeMap类型的方法增加NS后缀表示创建或查找对应命名空间的节点

importNode(复制的节点,是否复制子节点的布尔值)从文档导入另一文档

isSameNode和isEqualNode比较节点

获取框架文档节点:IE8+使用contentDocument,之前使用contentWindow.document

样式

样式驼峰,getComputedStyle或者IE的currentStyle获取计算样式.

offsetHeight
offsetWidth
:包括元素的边框,滚动条,内边距和内容(可见区域)

offsetLeft
offsetTop
是相对offsetParent来说的,要获取相对页面的偏移可以递归或者使用
getBoundingClientRect
,IE8前起点是(2,2)

clientHeight
clientWidth
:包括元素内边距和内容

scrollHeight
scrollWidth
:包括滚动内容的元素大小,其中
scrollLeft
scrollTop
可以获取和控制滚动条的高度

DOM2遍历:

NodeIterator
TreeWalker

范围

Range是一种fragment(HTML片断),它包含了节点或文本节点的一部分。 可以通过document.createRange()或selection对象的getRangeAt()方法获得。

createRange()是在2级DOM里定义的一个方法,它属于document对象。IE是不支持此方法的,因此需要检测浏览器的支持性。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: