太简单了!国外的50个JavaScript入门级面试题

3,192 阅读5分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 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

👉 推文地址

image-20220412095823969.png

原文中列出了50个 JavaScript 的入门级问题,题目难度比较低,但没提供答案。

有几个题目还考察了开发规范,比如 gitflow 流程RESTful风格架构

我整理以后,贴上答案加了一些解释、示例。

image-20220412152739040.png

目录

  1. Java和JavaScript有什么区别
  2. JavaScript有哪些数据类型
  3. 什么是DOM
  4. 什么是变量
  5. 什么是数组
  6. 什么是对象
  7. 什么是函数
  8. 什么是高阶函数
  9. 什么是JSON
  10. 局部变量和全局变量有什么区别
  11. var、const和let之间有什么区别
  12. =,==,===之间的区别
  13. 解释数组的.pop()和.push()方法
  14. 什么是箭头函数 =>
  15. 什么是Typescript,和JavaScript有什么不同
  16. 什么是Promise,举个使用的栗子
  17. 什么是async/await
  18. "break" 和 "continue" 语句有什么区别
  19. 如何检查对象是否含有某个属性
  20. 怎样检查数组是否包含某个值
  21. 如何检查一个数组的长度
  22. for循环和while循环有什么区别
  23. 什么时候用"&&",什么时候用"||"
  24. 什么是三元运算符
  25. 如何在JavaScript中创建一个对象
  26. 如何在JavaScript中创建一个数组
  27. 什么是this
  28. 什么是callback
  29. 变量命名要遵循什么规则
  30. 如何读取cookie
  31. localStorage 和 sessionStorage 有什么区别
  32. null 和 undefined 有什么区别
  33. 列举一些Javascript框架
  34. 什么是export 和 import
  35. 如何在Javascript中获取HTML元素
  36. 如何反转字符串
  37. 'use strict' 的作用是什么
  38. 描述gitflow的工作流程
  39. 如何用git更新你的本地仓库
  40. 什么是清除缓存,如何实现
  41. 什么是npm
  42. 什么是RESTful风格架构
  43. 什么是跨站攻击(XSS)
  44. 描述 "动态类型 "在 JavaScript 中的意思
  45. JavaScript有什么缺陷
  46. 如何为Javascript代码写测试
  47. 写一个循环,输出1-200中能被5整除的数字
  48. 写一个接受2个参数并返回参数乘积的函数
  49. 写一个带p标签的html页面
  50. 创建一个JS对象,带有名字、姓氏和ID属性,并有一个函数来返回全名

1. Java和JavaScript有什么区别

🤡他们的关系就像雷锋和雷峰塔,老婆和老婆饼,牛和蜗牛,除了名字像根本不一样。

  1. JavaScript运行不需要编译器;Java需要编译器。
  2. JavaScript是弱类型语言;Java是强类型语言,变量类型会在编译时检查
  3. JavaScript对象基于原型;Java对象基于类
JavaJavaScript
编程语言脚本语言
需要编译不需要编译
强类型语言弱类型语言
对象基于类对象基于原型

2. JavaScript有哪些数据类型

  • 字符串(String)
  • 数字(Number)
  • 布尔(Boolean)
  • 对空(Null)
  • 未定义(Undefined)
  • Symbol
  • 对象(Object)

💡 Symbol 是 ES6 新增数据类型,表示独一无二的值。

🚩 BigInt 是 ES10 中的数据类型,没有列出来

3 .什么是DOM

全称 Document Object Model(文档对象模型),是一颗以HTML元素为节点的树。

给JavaScript提供操作HTML的接口,例如:查询元素,修改元素,创建元素,删除元素等。

html.png

4. 什么是变量

变量是用来存储数据的容器,在JavaScript中分为局部变量全局变量,使用letvar定义

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 可以共享

local和session区别.png

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 开发规范,主要使用两个分支 MasterDevelopMaster 分支是只读分支,不能commit

  1. 开发新功能时从 Develop 上新建 Feature-1 分支,开发完后合并回 Develop

  2. 功能结束后,从 Develop 上新建 Release 分支,发布测试版本,之后 Release 分支用于修复BUG

  3. 待稳定后,从 Release 同时合并到 MasterDevelop 分支,在Master打上版本号

  4. Hotfix 用来修复生产环境中的紧急BUG,完成后要合并到 MasterDevelop 分支

gitflow.png

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 的代码,并且成功提交。

那么其他用户浏览留言时就会不停弹窗,影响正常使用。

image-20220409162952743.png

44. 描述 "动态类型 "在 JavaScript 中的意思

”动态类型“ 是指变量声明时不需要指定数据类型,代码运行时会自动检测数据类型,并且能随时转换。

const a = 'Maokai'  // 字符串
const b = 100 // 数字

console.log(a + b) // 👉 'Maokai100'

45. JavaScript有什么缺陷

阮一峰老师在2011年的博文中列举了10条缺陷

  1. 不适合开发大型程序
  2. 非常小的标准库
  3. null和undefined
  4. 全局变量难以控制
  5. 自动插入行尾分号
  6. 加号运算符
  7. NAN
  8. 数组和对象的区分
  9. == 和 ===
  10. 基本类型的包装对象

原文

💡 我还搜到了一些其他观点


  • 较大的前端项目,配置过程繁琐

  • 源码在浏览器里能直接看到,无法加密

  • DOM解析速度慢

  • JavaScript 发生错误时会停止渲染整个网站

  • 不同浏览器的兼容性不同,开发者需要花时间处理

  • 编辑器调试不能像C++/JAVA那样高效

46. 如何为Javascript代码写测试

使用一些测试框架,比如 JestMochaChai Vitest

  1. 安装测试框架
  2. 编写测试用例
  3. 运行测试,检查测试结果

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万年薪的工作哪里找?