js面试题
约 2371 字大约 8 分钟
2025-06-01
五基一引
五个基本数据类型:Number String null Boolean Undefined ES6新增:BigInt Symbol
一个引用数据类型:ObJeact: 函数 数组 对象
1. typeof null 的结果是什么,为什么?
typeof null 的结果是Object。
ull 的值是机器码 NULL 指针(null 指针的值全是 0)
那也就是说null的类型标签也是000,和Object的类型标签一样,所以会被判定为Object。
2.请说明var let const 的区别【面试题】
- 会将变量定义提升到最前面
console.log(num) //undefined
var num = 100
var num
console.log(num)
num = 100
同一变量重复定义
var num = 100 console.log(num) // 100 var num = 200 console.log(num) // 200
let:先定义后使用
const:定义常量
- 先定义后用
- 不可重新赋值,不可改【应用数据类型可以更改属性值】
- 变量名采用大驼峰或全字母大写
- while
2. 数据类型转换
隐式转换: 在数据参与运算中 数据自动发生数据类型转换
- 数字和字符串
- 字符串与数字 相加 全部拼接为字符串
- 字符串与数字 相减 字符串全部站换为数字
- 字符串与数字 相乘 除 字符串全部转换为数字
10 + '10' // '1010'
'10' + 10 // '1010'
'10' - 10 // 0
10 - '10' // 0
10 * '10' // 100
- 数字和布尔
- 布尔转换为数字
true + 1 // 2
1 + true // 2
true == 1 //true
flase == 0 //true
- 特殊隐式转换[面试]
0 == '0' //true
'' == null //false
'' == undefined // false
null == undefined // true 值相同 类型不
- 案例
let a = '5';
let b = 3;
let result = a + b; // '53'
console.log(result);
let x = false;
let y = 1;
let result = x + y;
console.log(result); // 1
let str = 'Hello' - 1;
console.log(str); // NaN
let num = 10;
let str = '10';
let result = num == str;
console.log(result); true
let arr = [1, 2, 3];
let result = arr + 2;
console.log(result);
强制转换 通过调用方法 转换数据类型 parseInt()
二、ES6
1. new 关键字的作用
实例化 创建对象
面试题
创建了一个空对象 let phone = {}
将空对象指向 this{}
在构造函数里加属性 自动return 出来 给实例化对象
this 指向 调用方的实例对象
2. 箭头函数与普通函数的区别
(1)箭头函数比普通函数更加简洁
- 如果没有参数,就直接写一个空括号即可
- 如果只有一个参数,可以省去参数的括号
- 如果有多个参数,用逗号分割
- 如果函数体的返回值只有一句,可以省略大括号
- 如果函数体不需要返回值,且只有一句话,可以给这个语句前面加一个void关键字。
(2)箭头函数没有自己的this
- 箭头函数不会创建自己的this, 所以它没有自己的this,它只会在自己作用域的上一层继承this。所以箭头函数中this的指向在它在定义时已经确定了,之后不会改变。
(3)箭头函数继承来的this指向永远不会改变
(4)call()、apply()、bind()等方法不能改变箭头函数中this的指向
箭头函数没有自己的arguments
- 箭头函数没有自己的arguments对象。在箭头函数中访问arguments实际上获得的是它外层函数的arguments值。
2. map和Object的区别
Map | Object | |
---|---|---|
意外的键 | Map默认情况不包含任何键,只包含显式插入的键。 | Object 有一个原型, 原型链上的键名有可能和自己在对象上的设置的键名产生冲突。 |
键的类型 | Map的键可以是任意值,包括函数、对象或任意基本类型。 | Object 的键必须是 String 或是Symbol。 |
键的顺序 | Map 中的 key 是有序的。因此,当迭代的时候, Map 对象以插入的顺序返回键值。 | Object 的键是无序的 |
Size | Map 的键值对个数可以轻易地通过size 属性获取 | Object 的键值对个数只能手动计算 |
迭代 | Map 是 iterable 的,所以可以直接被迭代。 | 迭代Object需要以某种方式获取它的键然后才能迭代。 |
性能 | 在频繁增删键值对的场景下表现更好。 | 在频繁添加和删除键值对的场景下未作出优化。 |
数组操作【重要】
数据列表
let arr = new Array(1,2,3) // [1,2,3]
let arr = [1, 2, 3] // [1, 2, 3]
let arr = [1, '你好', null]
let arr = [{name: '小美'}, {name: '小赵'}]
- 使用数据
数字名[下标|索引]
let arr = [{name: '小美'}, {name: '小赵'}]
arr[1].name // 小赵
3.数组方法
数字排序
a - b => 从小到大
b - a => 从大到小
let arr = [{price: 100}, {price: 200}, {price: 300}]
arr.sort((a, b) => b.price - a.price)
console.log(arr)
非数字排序
let arr2 = ['2','a', 'A', '?']
arr2.sort() // 不传数据
console.log(arr2)
push 末尾添加元素
arr.push(添加元素1, 添加元素2)
pop 末尾删除元素
arr.pop()
unshift 头部添加
arr.unshift(添加元素)
shift 头部删除
arr.shift()
splice 任意位置曾 删 改
arr.splice(操作下标开始下标,删除个数,新增元素1,新增元素2)
let arr = [1, 23, 45, 66] // 索引为3修改为1000 arr.splice(3, 1, 1000) // 删除23 arr.solice(1, 1) // 在45添加100,200 arr.splice(2, 0, 100, 200) => 索引为2开始加
reverse() 数组内容反转
4. 常见的DOM操作有哪些
1)DOM 节点的获取
DOM 节点的获取的API及使用:
javascript 体验AI代码助手 代码解读复制代码getElementById // 按照 id 查询
getElementsByTagName // 按照标签名查询
getElementsByClassName // 按照类名查询
querySelectorAll // 按照 css 选择器查询
// 按照 id 查询
var imooc = document.getElementById('imooc') // 查询到 id 为 imooc 的元素
// 按照标签名查询
var pList = document.getElementsByTagName('p') // 查询到标签为 p 的集合
console.log(divList.length)
console.log(divList[0])
// 按照类名查询
var moocList = document.getElementsByClassName('mooc') // 查询到类名为 mooc 的集合
// 按照 css 选择器查询
var pList = document.querySelectorAll('.mooc') // 查询到类名为 mooc 的集合
2)DOM 节点的创建
创建一个新节点,并把它添加到指定节点的后面。 已知的 HTML 结构如下:
html 体验AI代码助手 代码解读复制代码<html>
<head>
<title>DEMO</title>
</head>
<body>
<div id="container">
<h1 id="title">我是标题</h1>
</div>
</body>
</html>
要求添加一个有内容的 span 节点到 id 为 title 的节点后面,做法就是:
javascript 体验AI代码助手 代码解读复制代码// 首先获取父节点
var container = document.getElementById('container')
// 创建新节点
var targetSpan = document.createElement('span')
// 设置 span 节点的内容
targetSpan.innerHTML = 'hello world'
// 把新创建的元素塞进父节点里去
container.appendChild(targetSpan)
3)DOM 节点的删除
删除指定的 DOM 节点, 已知的 HTML 结构如下:
javascript 体验AI代码助手 代码解读复制代码<html>
<head>
<title>DEMO</title>
</head>
<body>
<div id="container">
<h1 id="title">我是标题</h1>
</div>
</body>
</html>
需要删除 id 为 title 的元素,做法是:
javascript 体验AI代码助手 代码解读复制代码// 获取目标元素的父元素
var container = document.getElementById('container')
// 获取目标元素
var targetNode = document.getElementById('title')
// 删除目标元素
container.removeChild(targetNode)
或者通过子节点数组来完成删除:
javascript
体验AI代码助手
代码解读
复制代码// 获取目标元素的父元素var container = document.getElementById('container')// 获取目标元素var targetNode = container.childNodes[1]// 删除目标元素container.removeChild(targetNode)
4)修改 DOM 元素
修改 DOM 元素这个动作可以分很多维度,比如说移动 DOM 元素的位置,修改 DOM 元素的属性等。
将指定的两个 DOM 元素交换位置, 已知的 HTML 结构如下:
javascript 体验AI代码助手 代码解读复制代码<html>
<head>
<title>DEMO</title>
</head>
<body>
<div id="container">
<h1 id="title">我是标题</h1>
<p id="content">我是内容</p>
</div>
</body>
</html>
现在需要调换 title 和 content 的位置,可以考虑 insertBefore 或者 appendChild:
javascript 体验AI代码助手 代码解读复制代码// 获取父元素
var container = document.getElementById('container')
// 获取两个需要被交换的元素
var title = document.getElementById('title')
var content = document.getElementById('content')
// 交换两个元素,把 content 置于 title 前面
container.insertBefore(content, title)
5, ajax、axios、fetch的区别
- AJAX Ajax 即“AsynchronousJavascriptAndXML”(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术。
)Fetch fetch号称是AJAX的替代品,是在ES6出现的,使用了ES6中的promise对象。Fetch是基于promise设计的。Fetch的代码结构比起ajax简单多。fetch不是ajax的进一步封装,而是原生js,没有使用XMLHttpRequest对象。
fetch的优点:
- 语法简洁,更加语义化
- 基于标准 Promise 实现,支持 async/await
- 更加底层,提供的API丰富(request, response)
- 脱离了XHR,是ES规范里新的实现方式
fetch的缺点:
fetch只对网络请求报错,对400,500都当做成功的请求,服务器返回 400,500 错误码时并不会 reject,只有网络错误这些导致请求不能完成时,fetch 才会被 reject。
fetch默认不会带cookie,需要添加配置项: fetch(url, {credentials: 'include'})
Axios Axios 是一种基于Promise封装的HTTP客户端,其特点如下:
浏览器端发起XMLHttpRequests请求
node端发起http请求
支持Promise API
监听请求和返回
对请求和返回进行转化
取消请求
自动转换json数据