JS学习笔记

75 阅读5分钟

1. 跨域

  • 协议、域名、端口号中任意一个不相同时,都算作不同域。不同域之间请求资源,都算是跨域。
  • 同源策略限制以下几种行为:
    1. Cookie、LocalStorage 和 IndexDB 无法读取
    2. DOM 和 JS 对象无法获得
    3. AJAX 请求不能发送

2. 对 JavaScript 的作用域、作用域链的理解。

  • 在 JavaScript 中有两种作用域类型:
    1. 局部作用域:只能在函数内部访问它们。
    2. 全局作用域:网页的所有脚本和函数都能够访问它。
    • JavaScript 拥有函数作用域:每个函数创建一个新的作用域。
    • 作用域决定了变量的可访问性(可见性)。
    • 函数内部定义的变量从函数外部是不可访问的(不可见的)。
  • 作用域链:
    • 当查找变量的时候,会先从当前上下文的变量对象中查找。
    • 如果没有找到,就会从父级(词法层面上的父级)执行上下文的变量对象中查找,一直找到全局上下文的变量对象,也就是全局对象。
    • 这样由多个执行上下文的变量对象构成的链表就叫做作用域链。

3. async、await 与 Promise 的区别

/--------- Promise概念:---------/

  • Promise 是异步编程的一种解决方案,比传统的解决方案(回调函数和事件)更合理、更强大。简单地说,Promise好比容器,里面存放着一些未来才会执行完毕(异步)的事件的结果,而这些结果一旦生成是无法改变的。 /--------- async await概念:---------/
  • async、await 也是异步编程的一种解决方案,它是 Generator 函数的语法糖,拥有内置执行器,不需要额外的调用会自动执行并输出结果,它返回的是一个 Promise 对象。
  • 两者的区别:
    • Promise的出现解决了传统回调函数导致的“地狱回调”问题,但它的语法导致了它向纵向发展形成了一个回调链,遇到复杂的业务场景,这样的语法显然也是不美观的。而async await代码看起来会简洁些,它使得异步代码看起来像同步代码,await的本质是可以提供等同于”同步效果“的等待异步返回能力的语法糖,只有这一句代码执行完,才会执行下一句。
    • async await 与 Promise 一样,是非阻塞的。
    • async await 是基于 Promise 实现的,可以说是改良版的Promise,它不能用于普通的回调函数。

4. 防抖和节流

  • 防抖(debounce):在事件被触发一段时间后再执行回调函数,如果在这段时间内事件再次被触发,则重新计时。
    • 应用场景:登录、调整浏览器窗口大小、input 输入
  • 节流(throttle):规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效。
    • 应用场景:scroll 事件

5. 闭包

  • 闭包指的是那些引用了另一个函数作用域中变量的函数,通常是在嵌套函数中实现的
  • 用途:读取函数内部的变量并让这些变量始终保存在内存中
  • 优点:1.可以避免全局变量的污染;2.可以缓存变量
  • 缺点:因为闭包会保留它们包含函数的作用域,所以比其他函数更占用内存。过度使用闭包可能导致内存过度占用,甚至造成内存泄漏
  • 使用闭包的注意点:在退出函数之前,将不使用的局部变量全部删除

6. JS事件循环机制

  1. js是单线程运行的,在执行代码的时候,通过将不同函数的执行上下文压入执行栈中来保证代码的有序执行。
  2. 在执行同步代码的时候,如果遇到了异步事件,js引擎并不会一直等待其返回结果,而是会将这个事件挂起,继续执行执行栈中的其他任务。
  3. 当异步事件执行完毕后,再将异步事件对应的回调加入到与当前执行栈不同的另一个任务队列中等待执行。
  4. 任务队列可以分为宏任务队列和微任务队列,当前执行栈中的事件执行完毕后,js引擎首先会判断微任务队列中是否有任务可以执行,如果有就将微任务队首的事件压入栈中执行。
  5. 当微任务队列中的任务都执行完成后再去执行宏任务队列中的任务。
  • 微任务包括 Promise 的回调、node 中的 process.nextTick、对 Dom 变化监听的 MutationObserver。
  • 宏任务包括 script 脚本的执行、setTimeout、setInterval、setImmediate 一类的定时事件,还有 I/O 操作、UI 渲染等。

7. 原型链

  • 当我们访问对象的一个属性或方法时,会先在对象自身中寻找,如果有则直接使用,如果没有则会去原型对象中寻找,如果找到则直接使用。如果还没有则去原型的原型中寻找,直到找到Object对象的原型,Object对象的原型没有原型,如果在Object对象的原型中依然没有找到,则返回undefined。这样一条向上查找的路径就是原型链