JS红宝书学习记录(三)
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()方法,四个参数:
-
url
-
窗口目标(比如topFrame,如果有该窗口就在加载在这,否则新建新窗口“topFrame”)
特殊名称:
-
_blank - URL加载到一个新的窗口。这是默认
- _parent - URL加载到父框架
- _self - URL替换当前框架
- _top - URL替换当前顶层即浏览器框架
-
特性字符串
-
表示新页面是否取代浏览器历史记录中记载当前页面的布尔值。
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类型:
-
ELEMENT_NODE :元素节点
属性:id,title,lang,dir,className
可以通过document.createElement创建
-
ATTRIBUTE_NODE
-
TEXT_NODE :文本节点
可以通过document.createTextNode()创建,HTML编码的有效方式。
-
CDTA_SECTION_NODE:基于XML的文档,表示CDATA区域
-
ENTITY_REFERENCE_NODE
-
ENTITY_NODE
-
PROCESSING_INSRUCTION_NODE:处理指令
-
COMMENT_NODE:注释节点,如 <! --></–>
-
DOCUMENT_NODE:文档节点
属性:documentElement(访问子元素),body,title,URL,domain,referrer
方法:getElementById(),getElementByTagName(),getElementByName(),write()
-
DOCUMENT_TYPE_NODE:文档注释,如”<!DOCTYPE>“
-
DOCUMENT_FRAGMENT_NODE:文档片段,轻量级文档,可以包含和控制节点,但不占用资源。(可以当成仓库使用,保存未来可能使用的节点)
-
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是不支持此方法的,因此需要检测浏览器的支持性。
- JS红宝书学习记录(五)
- JS红宝书学习记录(四)
- js学习记录9
- js 学习记录(四)一些总结
- 学习记录——node.js(二)
- JS函数易错点及难点学习记录
- css+js 学习记录
- Cocos2d-js 学习:imageView 简单API记录
- 转行前端自我学习养成记之js学习记录篇——<DOM编程艺术>学习记录(二)
- Backbone.js学习记录 Hello World!
- Three.js 学习记录 之 几何体(一)
- JS学习记录 - 浏览器对象
- js小案例效果学习记录--倒计时
- js学习记录(二)《js高级程序设计》笔记1
- 20101124 学习记录:Js的一些触发事件onblur等 & 获取当前日期并判断
- 学习记录——node.js(一)
- js学习笔记:记录一次apply和call方法的使用
- 廖雪峰js教程学习记录——JSON
- js和jquery中循环的退出和继续学习记录
- Typescript学习记录 - 不同于js的数据类型