「这是我参与2022首次更文挑战的第40天,活动详情查看:2022首次更文挑战」
1实现一个惰性函数
能使用惰性函数的必定是一对一的,就是一个入参必定对应一个返回值。我们就可以把之前计算过的结果保留下来,下次遇到之前算过的,就直接从缓存列表中取,不用再次计算。
通用的缓存就是一个哈希映射。 比如我们来一个斐波那契。递归版就适合惰性函数,迭代版的效果更好。
const fibMap = new Map()
function fib(n){
if( fibMap.has(n)){ return fibMap.get(n)}
if( n < 2){
fibMap.set( n, n)
return n ;
}
let fn = fib( n -1) + fib(n -2) ;
fibMap.set( n,fn) ;
return fn ;
}
2 innerHTML、 nodeValue与 textContent, innertext
innerHTML会按html语法解析传递的字符, 它的值就是当前元素的内部的html代码。所以如果含有script标签会自动转义。
textContent就比较复杂,先说innerText,这个的值作为一般的渲染元素来说就是在页面上渲染出来的内容,如果是script,或者注释节点等,那就是内部包含的字符。如果设置此属性,会将当前节点的子节点全部移除然后添加一个文本节点。
而textContent,不仅包含节点的渲染的内容,还包含其子节点的textContent,意思是说假如含有注释和script这样的子节点,会把它门内部的文本一并带出来。 innertext会受css的影响,而textContent不会。
nodeValue就要分节点类型了,对于注释节点和文本节点就是其文本内容, 属性节点就是其属性值, 其他节点为Null。 ProcessingInstruction 和 CDATA 片段不应该在 HTML 中被使用,所以我们就不管这种节点类型了
3获取元素属性值
el.getAttribute('propname'), 或者直接用点语法el.propName
通过 el.attributes可以访问到元素的数性节点,要获取其值,就需要el.attributes.name.value.唯一值得一提的是,class在这里就是class 而用上面两种方法则是className。 但是就如同红宝书所说我也喜欢用上面两种方法,属性节点什么的可以废除了。
4 查找元素的方式
getElementsBy 方法族 id className tagName Name tagNameNs 除了id之外 返回值都是htmlCollection,实时的元素集合。
querySelector() 通过选择器查找,返回找到的第一个元素。 all 方法也是选择器,但是返回找到的全部nodeList,不过仅仅是快照,
谁调用就在谁的返回内查找, 可以是document 也可以是任意一个元素节点。至于childNodes这能算是查找方式吗,children是子元素,node是子节点。
5html页面上的一个按钮添加 onclick事件处理,有几种方法?
1 在script里声明函数, 直接写到标签上,注意标签里要的一段逻辑而不是函数名,
2 获取这个元素,然后修改其onclick 属性, 或者调用其addEventListener。 这两种方式是互不干扰的。
6 window常用属性(对象)
const {devicePixelRatio, location, history, localStorage,sessionStorage, isSecureContext,navigator} = window
当然了使用的时候,不要解构。
dpr, 设备的 物理分辨与逻辑分辨率之比。
loaction ,location对象,用于获取修改当前url
history 历史状态管理,常用于跳转历史记录,前进后退,也可以改变当前
sessionStorage 和localStorage,都是本地存储的对象,用于存储数据,由于sessionStorage只能被同源页面访问,并且会在窗口关闭之后自动清除。
navigator, 当前应用程序(浏览器)的相关信息,经常使用navifgator.userAgent来识别浏览器,尽管这不一定可靠。 这个是属性是只读属性
7 实现每隔一秒钟弹出一个对话框,且此弹出过程持续5秒钟
一个很老的题了,说实话,一开始,没意识到这题要考啥。 注意,alert方法是会阻塞线程的。
假如,就写一个setInterval(()=> {alert()}, 1000);显然不行,因为只持续五秒,简单的说需要在五秒后关闭它。 来个计数器,到5就清了它 clearInterval, 也不太行,因为alert不点确定就阻塞了,最后肯定大于五秒。
所以需要另外一个定时器,来清除它,同时也清除自身。
let id= setInterval(function() {alert("Hello JavaScript");},1000)
let id2 = setTimeout( function( ) {clearInterval(id) ;clearTimeout(id2) } , 5*1000)
其实这样仍然不行,因为alert 会阻塞, 你可能会认为定时器异步,请理解事件轮循 。当前宏任务没有结束,被阻塞了,肯定不会开启下一轮的。 定时器是在一段时间后开始执行,实际上就是在五秒后把这个代码放进宏任务栈里。 所以在这之前。如果发生了阻塞,你这个五秒就有可能要延时了。
8 创建 删除 添加 移动节点
创建,create族函数 element, fragment TextNode.
删除,1是找到父节点,el.removeChild(node),2是节点的自我删除, el.remove()这个方法尚未成为标准。
添加,1是找到父节点 el.appendChild(),末尾 ,2 是 找到兄弟节点el.insertBefore()
复制 node.cloneNode.
移动就是 复制加删除加添加。没有移动
9 document.ready onload的区别
不好意思,dom对象没有ready这个事件,倒是有一个onreadstatechange事件,不过这个事件不太好用,不过可以用dom.readystate来判断当前状态。
吐槽完毕,他估计想问 DOMContentLoaded事件,只能用addeventListener.
这个事件表示dom树已经构建完毕,而不必等待样式表,图片或者子框架完成加载, 这个时候,已经可以使用一些dom操作了。如给元素绑定事件。
而load则是全部加载完毕。
10 Dom是那种基本的数据结构
树结构。 看清题目,是数据结构,不是js数据类型。
dom 常用操作
增 创建节点 createElement(tagName) createTextNode() 等等
删除 节点, 移除属性 node.remove, document.removeAttibute
改 修改属性 setAttribute()
查 document.get by queryselector
Dom节点的Attribute和Property有和区别
一般来说,这两者区别不大,attr是一个元素作为html标签的属性,比如class. prop是作为一个js对象的属性,比如className.
除了像className class 之外,大部分attr和prop都是一样的,也就是直接操作js对象和用setAttribute效果一样,可以认为setAttribute 是dom规范,而js也能操作则是dom在js里的实现。
react 采用的就是className 后者。
dom的基本优化原则
批量操作,不要少量多次,要大量一次。把要操作的dom的节点放入文档碎片。修改完毕之后再放回去。