每日一记
递归
递归:调用函数时调用自身
最大的嵌套调用次数(包括首次)被称为 递归深度。
两种思考方式:
1.迭代思路:使用 for 循环
2.递归思路:简化任务,调用自身
堆栈
堆和栈是cpu的两个部分,栈用于存储数据,堆
遵守先入后出原则,存入数据是压栈,放出数据叫弹栈POP(内存的数据不删除,但是放入回收站)
如果只入不出(没有return)就会栈溢出,导致程序错误
执行上下文和堆栈:
执行上下文是一个内部数据结构,它包含有关函数执行时的详细细节:当前控制流所在的位置,当前的变量,this 的值(此处我们不使用它),以及其它的一些内部细节。
一个函数调用仅具有一个与其相关联的执行上下文。
函数进行嵌套调用时:
当前函数被暂停;
1.与它关联的执行上下文被一个叫做 执行上下文堆栈 的特殊数据结构保存;
2.执行嵌套调用;
3.嵌套调用结束后,从堆栈中恢复之前的执行上下文,并从停止的位置恢复外部函数。
Rest 参数与 Spread 语法
当我们在代码中看到 “…” 时,它要么是 rest 参数,要么是 spread 语法。
有一个简单的方法可以区分它们:
若 … 出现在函数参数列表的最后,那么它就是 rest 参数,它会把参数列表中剩余的参数收集到一个数组中。
若 … 出现在函数调用或类似的表达式中,那它就是 spread 语法,它会把一个数组展开为列表。
使用场景:
Rest 参数用于创建可接受任意数量参数的函数。
Spread 语法用于将数组传递给通常需要含有许多参数的函数。
我们可以使用这两种语法轻松地互相转换列表与参数数组。
旧式的 arguments(类数组且可迭代的对象)也依然能够帮助我们获取函数调用中的所有参数。
垃圾收集
通常,函数调用完成后,会将词法环境和其中的所有变量从内存中删除。因为现在没有任何对它们的引用了。与 JavaScript 中的任何其他对象一样,词法环境仅在可达时才会被保留在内存中。
但是,如果有一个嵌套的函数在函数结束后仍可达,则它将具有引用词法环境的[[Environment]] 属性。
如果在(外部)函数执行完成后,它的词法环境仍然可达。因此,此词法环境仍然有效。
若要删除则需要令词法环境对象变得不可达
属性标志
value
writable — 如果为 true,则值可以被修改,否则它是只可读的。
enumerable — 如果为 true,则会被在循环中列出,否则不会被列出。
configurable — 如果为 true,则此属性可以被删除,这些特性也可以被修改,否则不可以。
浏览器环境,规格
能运行 JavaScript 的平台称为主机环境
包含DOM,BOM,JavaScript
文档对象模型(DOM)
将所有页面内容表示为可以修改的对象
浏览器对象模型(BOM)
表示由浏览器(主机环境)提供的用于处理文档(document)之外的所有内容的其他对象
例如:
navigator 对象提供了有关浏览器和操作系统的背景信息
navigator.userAgent —— 关于当前浏览器
navigator.platform —— 关于平台(有助于区分 Windows/Linux/Mac 等)
location 对象允许我们读取当前 URL,并且可以将浏览器重定向到新的 URL
DOM 树
概念:
DOM 将 HTML 表示为标签的树形结构。
每个树的节点都是一个对象。
标签被称为 元素节点(或者仅仅是元素),元素内的文本形成 文本节点,被标记为 #text。一个文本节点只包含一个字符串。它没有子项,并且总是树的叶子。
自动修正:
浏览器遇到格式不正确的 HTML,它会在形成 DOM 时自动更正它。
浏览器开发工具元素(Elements)选项卡:
Styles —— 我们可以看到按规则应用于当前元素的 CSS 规则,包括内建规则(灰色)。几乎所有内容都可以就地编辑,包括下面的方框的 dimension/margin/padding。
Computed —— 按属性查看应用于元素的 CSS:对于每个属性,我们可以都可以看到赋予它的规则(包括 CSS 继承等)。
Event Listeners —— 查看附加到 DOM 元素的事件侦听器(我们将在本教程的下一部分介绍它们)。
节点属性:
每个 DOM 节点都属于一个特定的类。这些类形成层次结构(hierarchy)。完整的属性和方法集是继承的结果。
主要的 DOM 节点属性有:
nodeType
我们可以使用它来查看节点是文本节点还是元素节点。它具有一个数值型值(numeric value):1 表示元素,3 表示文本节点,其他一些则代表其他节点类型。只读。
nodeName/tagName
用于元素名,标签名(除了 XML 模式,都要大写)。对于非元素节点,nodeName 描述了它是什么。只读。
innerHTML
元素的 HTML 内容。可以被修改。
outerHTML
元素的完整 HTML。对 elem.outerHTML 的写入操作不会触及 elem 本身。而是在外部上下文中将其替换为新的 HTML。
nodeValue/data
非元素节点(文本、注释)的内容。两者几乎一样,我们通常使用 data。可以被修改。
textContent
元素内的文本:HTML 减去所有 <tags>。写入文本会将文本放入元素内,所有特殊字符和标签均被视为文本。可以安全地插入用户生成的文本,并防止不必要的 HTML 插入。
hidden
当被设置为 true 时,执行与 CSS display:none 相同的事。
DOM 节点还具有其他属性,具体有哪些属性则取决于它们的类。例如,<input> 元素(HTMLInputElement)支持 value,type,而 <a> 元素(HTMLAnchorElement)则支持 href 等。大多数标准 HTML 特性(attribute)都具有相应的 DOM 属性。
弹窗和 window 的方法
window.open(‘https://javascript.info/')打开一个具有给定 URL 的新窗口
阻止弹窗:
1.阻止除了用户触发的事件之外的弹窗
// 弹窗被阻止
window.open('https://javascript.info');
// 弹窗被允许
button.onclick = () => {
window.open('https://javascript.info');
};
2.浏览器可以接受不同时间的延迟,超过这个时间则移除“信任”
// 1 秒后打开弹窗
setTimeout(() => window.open('http://google.com'), 1000);
window.open
打开一个弹窗的语法是 window.open(url, name, params)
其中params是width=200,height=100
窗口功能
menubar(yes/no)—— 显示或隐藏新窗口的浏览器菜单。
toolbar(yes/no)—— 显示或隐藏新窗口的浏览器导航栏(后退,前进,重新加载等)。
location(yes/no)—— 显示或隐藏新窗口的 URL 字段。Firefox 和 IE 浏览器不允许默认隐藏它。
status(yes/no)—— 显示或隐藏状态栏。同样,大多数浏览器都强制显示它。
resizable(yes/no)—— 允许禁用新窗口大小调整。不建议使用。
scrollbars(yes/no)—— 允许禁用新窗口的滚动条。不建议使用。
跨窗口通信
“同源(Same Origin)”策略(保护用户免遭信息盗窃)限制了窗口(window)和 frame 之间的相互访问。
如果两个 URL 具有相同的协议,域和端口,则称它们是“同源”的。
“同源”策略规定:
1.如果我们有对另外一个窗口的引用,并且该窗口是同源的,那么我们就具有对该窗口的全部访问权限。
2.否则,就无法访问该窗口中的任何东西。唯一的例外是 location:我们可以修改它(进而重定向用户)。但是我们无法读取 location(因此,我们无法看到用户当前所处的位置,也就不会泄漏任何信息)。
点击劫持攻击
原理:
1.访问者被恶意页面吸引
2.页面上有一个看起来无害的链接
3.放置了一个透明的iframe标签,通常通过 z-index 实现的
点击劫持是对点击事件,而非键盘事件
防御:
1.阻止因更改 beforeunload 事件处理程序中的 top.location 而引起的过渡————当 iframe 试图更改 top.location 时,访问者会收到一条消息,询问他们是否要离开页面
2.利用Sandbox 特性,添加sandbox=”allow-scripts allow-forms” 的 iframe。允许脚本和表单。但没有 allow-top-navigation,因此禁止更改 top.location 。
3.服务器端 header X-Frame-Options 可以允许或禁止在 frame 中显示页面。(副作用大)
4.具有 samesite 特性的 cookie 仅在网站是通过直接方式打开(而不是通过 frame 或其他方式)的情况下才发送到网站。