js中必考面试题

86 阅读5分钟

鹏北海,凤朝阳。又携书剑路茫茫。
大佬如果发现写的有问题一定要提出来,搬砖路漫漫请多多指教~

JS有几种基础数据类型?

undefined,null,boolean,number,string | symbol,bigInt

symbol:独一无二且不可变 =>用于全局变量冲突、内部变量覆盖

bigInt:任意精度正数/安全地存储和操作大数据,即便超出了number的安全整数范围

  • 基础数据类型通常如何进行分类?

可以分为:原始数据类型 + 引用数据类型

原始数据类型:undefined,null,boolean,number,string

引用数据类型:对象,数组,函数

  • 使用起来有什么区别?
  1. 效果不同:

原始数据类型直接赋值后,不存在引用关系

属性引用关系

  1. 存储位置不同

栈:原始数据类型 => 先进后出栈维护结构 => 栈区由编译器自动分配释放 => 临时变量方式

堆:引用数据类型 => 堆内存由开发者进行分配 => 直到应用结束

  • 使用过程中是如何区分的?

原始数据放置在栈中,空间小、大小固定、操作频繁

引用类型数据量大、大小不固定,赋值给的是地址

函数和箭头函数的区别?

  • 函数和箭头函数是js中定义函数的两种不同方式
  • this关键字: 箭头函数没有自己的this,而常规的函数有自己的this
  • 作为构造函数: 箭头函数不能作为构造函数,不能使用new关键字实例化箭头函数,会抛出错误。而常规函数可以。
  • 原型属性: 由于箭头函数不能用作为构建函数,所以它没有prototype属性。

Promise 的作用和用法?

promise是javascript中处理异步操作的一种对象。它允许你有更好的方式组织异步代码,避免了回调地狱(Callback Hell)的问题。Promise 对象代表了一个异步操作的最终完成(或失败)及其结果值。

  • Promise 的状态:

Pending(进行中):初始化状态

Fulfilled(已成功):操作成功完成

Rejected(已失败):操作失败完成

  • Promise 的用法:
  1. 创建 Promise

你可以通过 new Promise 构造函数来创建一个 Promise 对象:

const promise = new Promise((resolve, reject) => { 
    // 异步操作 
    // ... 
    if (/* 异步操作成功 */) { 
        resolve(value); // value 是异步操作返回的结果值 
    } else { 
        reject(error); // error 是失败原因 } 
});

使用 Promise

当 Promise 对象被创建后,你可以用 then 方法链式调用,来组织异步操作的执行顺序。then 方法接受两个回调函数作为参数,第一个处理 resolve 的情况,第二个处理 reject的情况(通常我们使用 catch 方法处理 reject 的情况):

promise .then((value) => { 
    // 处理成功结果 
    console.log(value); 
})
.catch((error) => { 
    // 处理错误 
    console.error(error); 
});
  1. 链式调用 then 方法总是返回一个新的 Promise 对象,所以你可以进行链式调用:
const promise = new Promise((resolve, reject) => {
    resolve(1); 
}); 
promise.then((value) => { 
    console.log(value); // 输出 1 return value + 1; 
}) .then((value) => { 
    console.log(value); // 输出 2
});

闭包是什么?

闭包是一个函数和它对外部作用域的引用。这使得该函数可以访问其定义时的作用域,即使它被执行在一个不同的环境中。

  • 什么情况下使用闭包?

保持变量私有性:

闭包可以帮助我们创建私有变量,防止外部代码访问或者修改这些变量。

function createCounter() { 
    let count = 0; 
    return function() { 
    count++; 
    console.log(count); 
    } 
} 
const counter = createCounter(); 
counter(); // 输出: 1 
counter(); // 输出: 2 
// count 变量对外部是不可访问的,只能通过闭包中的匿名函数访问和修改。

维持异步操作状态:

在异步操作,如Promise或者事件监听器中,闭包可以帮助我们维持状态或者变量。

function asyncGreet(name) { 
    setTimeout(function() { 
        console.log("Hello, " + name);
    }, 1000); 
} 
asyncGreet("World"); // 1秒后输出: "Hello, World"

event loop(事件轮询) 过程

"事件轮询"(Event Loop)是JavaScript实现异步的一种方法,它允许JavaScript在等待异步操作的同时,如网络请求或定时任务等,继续运行其他代码。以下是事件轮询的简化描述:

  1. 同步代码,一行一行放在Call Stack执行
  2. 遇到异步,会先“记录”下,等待时机(定时、网络请求等)
  3. 时机到了,就移动到Callback Queue
  4. 如Call Stack 为空(即同步代码执行完)Event loop开始工作
  5. 轮询查找Callback Queue , 如有则移动到Call Stack执行
  6. 然后继续轮询查找(永动机一样)

什么是同源策略?

同源策略(Same-origin policy)是一种安全机制,被大多数 web 浏览器采纳。这个策略帮助防止某个网站的恶意脚本对另一个网站进行不安全的访问或交互,它是一种重要的 web 安全原则。

  • 同源策略简述:

定义:“同源”指的是三个主要的网站特征全部相同:

  1. 协议(例如,http 或 https)
  2. 域名(例如,example.com)
  3. 端口号(例如,80 或 443; 对于默认端口这个条件通常被省略)

只有当这三个条件全部匹配时,两个网页才算是同源。

限制: 同源策略主要限制了来自不同源的网站的以下几种行为:

  • Cookie、LocalStorage 和 IndexDB 的访问: 一个网页上的脚本通常无法访问另一个网页的这些资源。
  • DOM 的访问: 不同源的网页上的脚本无法访问对方的 DOM。
  • AJAX 请求: 大多数情况下,XMLHttpRequest 和 fetch 这样的网络请求API无法向不同源的服务器地址发送请求。

例外: 有一些方法允许跨域通信,即便存在同源策略的限制,例如:

  • CORS(跨域资源共享): 服务器可以设置特定的 HTTP 头,允许特定的外部访问。
  • JSONP: 通过
  • postMessage: 安全地实现跨源通信。
  • iframe 和相关技术: 虽有限制,但某些情况下可以使用。