一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情。
前言
看到一条推文
“ 50个最受欢迎的javascript入门级面试题,这个帖子可能决定你年薪10万美元工作的面试成败 ”
50 of the most popular javascript entry level interview questions. This thread could make or break your next interview for a $100k/year job
👉 推文地址
原文中列出了50个 JavaScript 的入门级问题,题目难度比较低,但没提供答案。
有几个题目还考察了开发规范,比如 gitflow 流程 、RESTful风格架构
我整理以后,贴上答案加了一些解释、示例。
目录
- Java和JavaScript有什么区别
- JavaScript有哪些数据类型
- 什么是DOM
- 什么是变量
- 什么是数组
- 什么是对象
- 什么是函数
- 什么是高阶函数
- 什么是JSON
- 局部变量和全局变量有什么区别
- var、const和let之间有什么区别
- =,==,===之间的区别
- 解释数组的.pop()和.push()方法
- 什么是箭头函数 =>
- 什么是Typescript,和JavaScript有什么不同
- 什么是Promise,举个使用的栗子
- 什么是async/await
- "break" 和 "continue" 语句有什么区别
- 如何检查对象是否含有某个属性
- 怎样检查数组是否包含某个值
- 如何检查一个数组的长度
- for循环和while循环有什么区别
- 什么时候用"&&",什么时候用"||"
- 什么是三元运算符
- 如何在JavaScript中创建一个对象
- 如何在JavaScript中创建一个数组
- 什么是this
- 什么是callback
- 变量命名要遵循什么规则
- 如何读取cookie
- localStorage 和 sessionStorage 有什么区别
- null 和 undefined 有什么区别
- 列举一些Javascript框架
- 什么是export 和 import
- 如何在Javascript中获取HTML元素
- 如何反转字符串
- 'use strict' 的作用是什么
- 描述gitflow的工作流程
- 如何用git更新你的本地仓库
- 什么是清除缓存,如何实现
- 什么是npm
- 什么是RESTful风格架构
- 什么是跨站攻击(XSS)
- 描述 "动态类型 "在 JavaScript 中的意思
- JavaScript有什么缺陷
- 如何为Javascript代码写测试
- 写一个循环,输出1-200中能被5整除的数字
- 写一个接受2个参数并返回参数乘积的函数
- 写一个带p标签的html页面
- 创建一个JS对象,带有名字、姓氏和ID属性,并有一个函数来返回全名
1. Java和JavaScript有什么区别
🤡他们的关系就像雷锋和雷峰塔,老婆和老婆饼,牛和蜗牛,除了名字像根本不一样。
- JavaScript运行不需要编译器;Java需要编译器。
- JavaScript是弱类型语言;Java是强类型语言,变量类型会在编译时检查
- JavaScript对象基于原型;Java对象基于类
| Java | JavaScript |
|---|---|
| 编程语言 | 脚本语言 |
| 需要编译 | 不需要编译 |
| 强类型语言 | 弱类型语言 |
| 对象基于类 | 对象基于原型 |
2. JavaScript有哪些数据类型
- 字符串(String)
- 数字(Number)
- 布尔(Boolean)
- 对空(Null)
- 未定义(Undefined)
- Symbol
- 对象(Object)
💡 Symbol 是 ES6 新增数据类型,表示独一无二的值。
🚩 BigInt 是 ES10 中的数据类型,没有列出来
3 .什么是DOM
全称 Document Object Model(文档对象模型),是一颗以HTML元素为节点的树。
给JavaScript提供操作HTML的接口,例如:查询元素,修改元素,创建元素,删除元素等。
4. 什么是变量
变量是用来存储数据的容器,在JavaScript中分为局部变量和全局变量,使用let和var定义
5. 什么是数组
数组是在一个变量中存储多个值
例如:var names = ['小明', '小红', '小刚']
6. 什么是对象
对象是一种无序的数据集合,由 ”键值对” 组成,值也可以是Function
const person = {
uid: '1838039173968382',
name: 'Maokai'
}
console.log(person) // 👉 { name: "Maokai", uid: "1838039173968382" }
7. 什么是函数
函数是可以通过外部调用的“子程序”(一组任务或计算值的语句),函数内容要写在{}里,使用函数前必须先定义函数
// 定义
function add(){
let rers = 1 +2
console.log(rers)
}
add() // 👉 3
8. 什么是高阶函数
函数参数中可以传入另一个函数的函数就是高阶函数,常用高阶函数:map() , reduce() , filter()
const arr = [1, 2, 3]
const arr2 = arr.map(item => item * 2)
console.log(arr2) //👉 [2, 4, 6]
9. 什么是JSON
JSON 是一种数据格式,由无序的”键值对” 组成,与JavaScript对象语法相似。
- JSON 字符串必须用双引号
- JSON 无法表示函数
- JSON 无法表示undefined
{
"name": "Maokai",
"uid": "1838039173968382"
}
10. 局部变量和全局变量有什么区别
作用域不同
全局变量:在函数外部定义,在JavaScript 代码的任何位置都能访问。
局部变量:在函数内部定义,只能在函数中访问,即在{}里。
// 全局变量
var uid = '1838039173968382'
// 局部变量
function action(){
let user = 'Maokai'
}
console.log(uid) // 👉 '1838039173968382'
console.log(user) // 👉 user is not defined
11. var、const和let之间有什么区别
var声明的作用域是全局或函数内,存在变量提升
let声明的作用域是所在代码块{}内,不存在变量提升
const声明常量,不能修改值
const声明的常量,如果是引用类型可被修改
12. =,==,===之间的区别
= 是赋值运算符
==和===都是比较运算符,他们主要区别是==操作符只比较两个值是否相等,而===操作符不仅要求值相等,而且要求类型相同。
例如,比较数字1和字符串'1' 时,==返回true,===返回false。原因是==先进行了强制类型转换
var a = 1
var b = '1'
console.log(a == b) // 👉 true
console.log(a === b) // 👉 false
13. 解释数组的.pop()和.push()方法
pop()方法,删除并返回数组最后一个元素
push()方法,在数组的尾端添加一个或多个元素,返回新的长度
💡 补充两个数组方法
shift()方法,删除并返回数组的第一个元素
unshift(),在数组的开头添加一个或更多元素,返回新的长度
const names = ['小明', '小红', '小刚', '小华']
names.pop()
console.log(names) // 👉 ['小明', '小红', '小刚']
names.push('小强')
console.log(names) // 👉 ['小明', '小红', '小刚', '小强']
names.shift()
console.log(names) // 👉 ['小红', '小刚', '小强']
names.unshift('小亮', '小三')
console.log(names) // 👉 ['小亮' , '小三', '小红', '小刚', '小强']
14. 什么是箭头函数 =>
箭头函数是更简洁的函数定义,不过没有自己的this,arguments,super。
箭头函数中只有一个return时可省略return 和花括号{}
const arr = [1, 2, 3]
const arr2 = arr.map(item => { return item * 2})
// 省略return和{}
const arr3 = arr.map(item => item * 2)
console.log(arr2) //👉 [2, 4, 6]
console.log(arr3) //👉 [2, 4, 6]
15. 什么是Typescript,和JavaScript有什么不同
TypeScript 是一种由微软开源的编程语言,它是 JavaScript 的超集,理解为添加了类型系统的JavaScript,可以编译成JavaScript 。
不同点
- TS是编程语言,需要编译;JS是脚本语言,无需编译
- TS提供编译时静态类型检查;JS不支持静态类型
- TS中的数据要求明确类型;JS不要求
16. 什么是Promise,举个使用的栗子
Promise对象用于表示一个异步操作的最终完成 (或失败)及其结果值。
共有3种状态
**Pending **是 Promise 的初始状态
**fulfilled **表示成功操作的状态
rejected 表示失败操作的状态
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('完成');
}, 1000);
})
.then(value => value + ' 第1次' )
.then(value => value + ' 第2次')
.then(value => console.log(value)) //👉 完成 第1次 第2次
17. 什么是async/await
async用于申明函数是异步的,await是等待异步函数执行完成。
async会返回Promise对象,await不需要写then就能得到返回值
// 栗子
async function load(){
const name = await getName()
const id = await getId()
}
18. "break" 和 "continue" 语句有什么区别
continue 语句只结束本次循环,break 语句则是结束整个循环。
for (let i = 0; i < 3; i++) {
if (i === 1) {
break
}
console.log(i)
}
//👉 0
for (let i = 0; i < 3; i++) {
if (i === 1) {
continue
}
console.log(i)
}
//👉 0 2
19. 如何检查对象是否含有某个属性
方法1(不含继承属性)
Object.keys(被检查得对象).includes('属性')
方法2(不含继承属性)
被检查得对象.Object.hasOwnProperty('属性')
方法3(含继承属性)
'属性' in 被检查得对象
const person = {
uid: '1838039173968382',
name: 'Maokai'
}
console.log(Object.keys(person).includes('uid')) // 👉 true
console.log(person.hasOwnProperty('uid')) // 👉 true
console.log('uid' in person) // 👉 true
20. 怎样检查数组是否包含某个值
方法1
数组.indexOf(查找值)
返回找到的索引值,-1表示找不到
方法2
数组.includes(查找值,开始查找的索引)
返回 true/false
索引可省略
方法3
数组.some(item => 查找条件)
找到返回true/否则返回false
const names = ['小明', '小红', '小刚', '小华']
console.log(names.indexOf('小红')) // 👉 1
console.log(names.includes('小红')) // 👉 true
console.log(names.some(item => item === '小亮')) // 👉 false
21. 如何检查一个数组的长度
数组.length获取数组长度
const names = ['小明', '小红', '小刚', '小华']
console.log(names.length) // 👉 4
22. for循环和while循环有什么区别
循环次数确定时用for,不确定时用while;循环中要改变循环条件时用while
所有for都可以写成while,while需要注意循环条件,处理不好会死循环
const names = ['小明', '小红', '小刚', '小华']
for (let i = 0; i < 4; i++) {
console.log(names[i])
}
// 👉 "小明" "小红" "小刚" "小华"
let i = 0
while (i < 4) {
console.log(names[i])
i++
}
// 👉 "小明" "小红" "小刚" "小华"
23. 什么时候用"&&",什么时候用"||"
&& 和 || 是逻辑运算符,当需要判断多个条件时,用到逻辑运算符
多个条件同时为 true 时用逻辑与 &&
有一个条件为 true 时用逻辑或 ||
补充一个逻辑非
!,取反
// 逻辑与
if (2 > 1 && 3 > 1){
console.log('条件都是true')
}
// 👉 '条件都是true'
// 逻辑或
if (0 > 1 || 3 > 1){
console.log('有一个条件是true')
}
// 👉 '有一个条件是true'
// 逻辑非
if (!(0 > 1)){
console.log('条件是flase,取反是ture')
}
// 👉 '条件是flase,取反是ture'
24. 什么是三元运算符
三元运算符作为 if else 的一种简写
条件 ? 条件为true时执行 : false时执行
const names = ['小明', '小红', '小刚', '小华']
names.includes('小明') ? console.log('找到了') : console.log('没找到')
// 👉 '找到了'
25. 如何在JavaScript中创建一个对象
方法1
const user = { name:'Maokai' }
方法2
const user = new Object();
user.name = 'Maokai'
方法3
function User(name){
this.name = name
}
const user1 = new User('Maokai')
26. 如何在JavaScript中创建一个数组
方法1
const names = ['小明', '小红']
方法2
const names = Array.of('小明', '小红')
方法3
const names = []
names.push('小明')
names.push('小红')
27. 什么是this
this表示它所属的对象,根据使用位置,具有不同的值
全局下this表示 window 对象,在函数体内 {} this 表示改函数所属对象
console.log(this) // 👉 window
const user = {
uid: '1838039173968382'
name: 'Maokai',
getNameAndID(){
return `${this.name}📍${this.uid}`
}
}
console.log(user.getNameAndID())// 👉 'Maokai📍1838039173968382'
28. 什么是callback
callback是回调函数,在一个函数执行完后要执行的函数就是callback。
一般来说,参数是一个函数,那么这个函数就是回调
function getUser(name, callback){
console.log(name)
callback()
}
getUser('Maokai',() => {
console.log('我是回调函数')
})
//👉 'Maokai' '我是回调函数'
29. 变量命名要遵循什么规则
- 首字母必须是
字母,_,$之一 - JavaScript变量区分大小写
- 不能使用关键字或保留字
30. 如何读取cookie
使用 document.cookie 读取所有cookie值
const myCookie = document.cookie
推荐使用 js-cookie操作cookie
读取使用 .get()
31. localStorage 和 sessionStorage 有什么区别
数据有效期不同
localStorage 关闭窗口也有效;sessionStorage 关闭窗口后数据就被清空
作用域不同
localStorage 在同源窗口中数据共享;sessionStorage 不能在窗口中共享,即使是同源
💡 一个页面中有多个iframe且同源时,sessionStorage 可以共享
32. null 和 undefined 有什么区别
null 是人为设置的,是表示 “无” 的值,是一个对象;转成数字是 0
undefined 表示 “缺省值”,此处应该有值,但没有定义;转成数字是 NaN
33. 列举一些Javascript框架
34. 什么是export 和 import
JavaScript 的模块化语法,使用 export 和 import 能将代码拆分成多个文件,有利于工程化开发
35. 如何在Javascript中获取HTML元素
方法1(通过ID)
// <input type="text" id="user"/>
document.getElementById('user')
方法2(通过name属性)
// <input type="text" name="userName" />
document.getElementsByName('userName')
方法3(通过标签名)
// <input type="text" />
document.getElementsByTagName('input')
方法4(通过类名)
// <input type="text" class="user-name"/>
document.getElementsByClassName('user-name')
方法5(通过选择器获取一个元素)
// <input type="text" class="user-name"/>
document.querySelector('.user-name')
方法6(通过选择器获取一组元素)
// <input type="text" class="user-name"/>
// <input type="text" class="user-name"/>
document.querySelectorAll('.user-name')
//👉 返回数组
36. 如何反转字符串
实现反转字符串的最简单的方法是for循环,这里用最少代码实现
const name = 'Maokai'
const reverse = str => str.split('').reverse().join('')
console.log( reverse(name) ) //👉 'iakoaM'
37. 'use strict' 的作用是什么
JavaScript 严格模式引入了更好的错误检查,消除代码不严谨的地方,减少怪异行为。
- 没有声明的变量不允许使用
- 禁止this指向全局对象
- 创建了eval()作用域
38. 描述gitflow的工作流程
gitflow 是一种 git 开发规范,主要使用两个分支 Master 和 Develop ,Master 分支是只读分支,不能commit
-
开发新功能时从
Develop上新建Feature-1分支,开发完后合并回Develop -
功能结束后,从
Develop上新建Release分支,发布测试版本,之后Release分支用于修复BUG -
待稳定后,从
Release同时合并到Master和Develop分支,在Master打上版本号 -
Hotfix用来修复生产环境中的紧急BUG,完成后要合并到Master和Develop分支
39. 如何用git更新你的本地仓库
方法1(最简单)
git pull
方法2(最安全)
# 以远程master分支创建本地temp分支
git fetch origin master:temp
# 比较本地master分支和temp分支差异
git diff temp
# 合并temp分支到本地master分支
git merge temp
# 删除temp分支
git branch -d temp
40. 什么是清除缓存,如何实现
在 Javascript 开发中缓存通常指浏览器缓存,缓存能提高网站性能,但也可能影响网站更新。
有时需要用一些方法阻止浏览器缓存数据
方法1(使用meta标签)
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
方法2(添加随机数)
// 在请求或引用文件的url上添加一个参数(名称随意)
const url = 'http://xxx.com'
const noCacheUrl = str => `${str}?t=${Math.random()}`
console.log(noCacheUrl(url)) // 👉 "http://xxx.com?t=0.4186289414907023"
方法3(添加请求头)
// 在请求中添加不缓存的请求头
// 'Cache-Control': 'no-cache'
41. 什么是npm
npm(Node Package Manager)是 Node.js的包管理器,可以让 Javascript 开发者能够更方便共享代码,共用代码
42. 什么是RESTful风格架构
😜 详细内容请出门左转阮一峰老师的 《理解RESTful架构》
REST(Representational State Transfer)翻译为 “表现层状态转移”,用一句话描述
URL定位资源,用HTTP动词(GET,POST,DELETE,DETC)描述操作
使用put,deleten,post,get 对应“增删改查”
// 不符合的接口定义
GET xxx.com/getUser
// REST接口定义(不在url中体现动作)
GET xxx.com/user
43. 什么是跨站攻击(XSS)
跨站脚本攻击(Cross-site scripting,XSS)指黑客往uHTML或DOM中注入恶意脚本,从而在用户浏览页面时对用户实施攻击的手段
🌰 举个栗子
攻击者在留言板上写了一段不停 alert 的代码,并且成功提交。
那么其他用户浏览留言时就会不停弹窗,影响正常使用。
44. 描述 "动态类型 "在 JavaScript 中的意思
”动态类型“ 是指变量声明时不需要指定数据类型,代码运行时会自动检测数据类型,并且能随时转换。
const a = 'Maokai' // 字符串
const b = 100 // 数字
console.log(a + b) // 👉 'Maokai100'
45. JavaScript有什么缺陷
阮一峰老师在2011年的博文中列举了10条缺陷
- 不适合开发大型程序
- 非常小的标准库
- null和undefined
- 全局变量难以控制
- 自动插入行尾分号
- 加号运算符
- NAN
- 数组和对象的区分
- == 和 ===
- 基本类型的包装对象
💡 我还搜到了一些其他观点
较大的前端项目,配置过程繁琐
源码在浏览器里能直接看到,无法加密
DOM解析速度慢
JavaScript 发生错误时会停止渲染整个网站
不同浏览器的兼容性不同,开发者需要花时间处理
编辑器调试不能像C++/JAVA那样高效
46. 如何为Javascript代码写测试
使用一些测试框架,比如 Jest、Mocha、Chai 、Vitest 等
- 安装测试框架
- 编写测试用例
- 运行测试,检查测试结果
47. 写一个循环,输出1-200中能被5整除的数字
for (let i = 1; i <= 200; i++) {
const res = i % 5 === 0
if (res) console.log(i)
}
48. 写一个接受2个参数并返回参数乘积的函数
function multiply(a, b) {
return a * b
}
49. 写一个带p标签的html页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Maokai</title>
</head>
<body>
<h1>50个流行的JavaScript面试题</h1>
<p>来自twitter上的50个题</p>
</body>
</html>
50. 创建一个JS对象,带有名字、姓氏和ID属性,并有一个函数来返回全名
function Person(a, b, c){
this.id = a
this.firstName = b
this.LastName = c
this.fullName = () => this.LastName + this.firstName
}
const my = new Person('1838039173968382','Maokai','lin')
console.log(my.fullName())
最后
🤡 问题我都会了,请问10万年薪的工作哪里找?