1. JS的数据类型(七种数据类型+新1)
null undefined
object
number bool symbol string
bigint
2. null 和undefined的区别是什么
-
undefined 是声明之后的
默认值但 null 不是 -
undefined一般是来给基本类型做未赋值
null 是给
对象做未赋值 (程序员一般 一个对象如果为空,会给null,而不是undefined)
总结 (对象就给null, 非对象就给undefined)
-
undefined 不是一个
关键字而null 是一个关键字
你可以声明一个变量是null,但是不能声明一个变量是undefined
- undefined 表示一个变量自然的、最原始的状态值,而 null 则表示一个变量被人为的设置为空对象,而不是原始状态。
3. typeof null 的结果是什么
- object
typeof 'str' // 'string'
typeof NaN // 'number'
typeof 1 // 'number'
typeof true // 'boolean'
typeof undefined // 'undefined'
typeof Symbol() // 'symbol'
typeof null // 'object'
4. 0.1+0.2的结果为什么不等于0.3
-
浮点数的精度问题,在内存中,0.1并不等于0.1, 0.2并不等于0.2 ,所以它们的结果是约等于0.3 , 并不是等于3
-
至于让它们相等,有个
Number.EPSILON的属性
5. typeof NaN的结果是什么
- number , 因为NaN只是一个不能表示的数字,但它还是一个数字
🈶6. let var const 的区别
let 和const 都只是块级作用域,不会变量提升且必须在声明之后使用,没有全局变量,不能重复声明变量
而var是全局作用域,不管你在哪声明,它都会影响全局,可以重复声明变量
let 和var 可以不需要设置初始值
但const 必须设置初始值
7. 箭头函数和普通函数的区别
- 箭头函数比普通函数更简洁
- 箭头函数没有自己的this
- 箭头函数没有arguments
- 箭头函数不能作为构造函数使用
- 箭头函数没有原型prototype
8. 箭头函数什么情况下可以省略它的return
- 只有一个语句
- 没有花括号
9. 箭头函数的this指向哪里
- 箭头函数本身是没有this的
- 指向外面的this
10. 你对JSON的理解
JavaScript Object Notation(JavaScript 对象表示法)
- JSON一种通用数据结构的语言
- 是用来代替XML 做数据交换
- JSON支持的数据类型 对象、数组、bool、string、number、null , 不支持函数
- 可以使用
JSON.parse()方法将数据转换为 JavaScript对象。 - 可以使用
JSON.stringify()方法将 JavaScript 对象转换为字符串
- JSON 与 JS 的区别
- JSON只支持双引号
- JSON没有undefined
- JSON不支持函数
- JSON不支持变量
11. Unicode 和 UTF-8 的区别
- Unicode是一个字符集,把世界上所有的文字编了一个号
- UTF-8是一种编码
12. 说说你对原型、原型链的理解
🈶13. 说说你对闭包的理解
什么是闭包:一个函数用到了外部的变量那么这个总和就是闭包
闭包的用途:闭包常用来间接访问一个变量,也就是说隐藏一个变量
关键点:用途,需要回答【隐藏局部变量,暴露操作函数】,用代码举例
const createAdd = ()=>{
let n = 0
return ()=>{
n += 1
console.log(n)
}
}
const add = createAdd()
add() // 1
add() // 2
闭包的缺点:闭包在IE有bug,增加内存使用量,故而会导致内存泄露
🈶14. 什么是立即执行函数,为什么要用
- 立即执行函数就是:声明一个匿名函数,马上调用这个匿名函数
- 作用:创建一个独立的作用域。这个作用域里面的变量,外面访问不到(即避免「变量污染」)
立即执行函数
15. 请说一下异步编程的实现方式
- 为什么要异步编程:为了实现多线程
- 回调函数
- Promise
- async 和await
- generator
🈶16. Promise(then、 catch、 all、 race)
- 如何创建一个 new Promise:
return new Promise((resolve,reject)=>{})
- 如何使用 Promise.prototype.then
const promise1 = new Promise((resolve, reject) => {
resolve('Success!')
})
promise1.then((value) => {
console.log(value)
})
Promise.catch的用法就是和then一样,先执行这个(then)再执行那个(catch)
- 如何使用 Promise.all,都成功才会调用
let Promise1 = new Promise(function(resolve,reject)=>{})
let Promise2 = new Promise(function(resolve,reject)=>{})
let Promise3 = new Promise(function(resolve,reject)=>{})
let p = Promise.all([Promise1,Promise2,Promise3])
p.then(function(){
},function(){
})
- 如何使用 Promise.race,谁第一个成功或失败,就认为是race的成功或失败
const promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 500, 'one')
})
const promise2 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'two')
})
Promise.race([promise1, promise2]).then((value) => {
console.log(value)
})
🈶17. 请问Promise解决了什么问题
- Promise 的用途: 是前端解决异步问题的方案,用于避免回调地域,让代码看起来更同步
18. 什么是同步,什么是异步,什么是异步函数
- 同步:能直接拿到结果
- 异步: 不能直接拿到结果
- 异步函数: 如果一个函数的返回值处于
setTimeout、AJAX(XMLHttpRequest)、AddEventListener,这三个东西内部,那么这个函数就是异步函数
注:不要把AJAX设置为同步
19. 并发与并行的区别
- 并发是宏观概念,表示A和B同时发生
- 并行是微观概念,表示CPU有多个核心,同时执行两个不同的任务
🈶20. 如何实现深拷贝****
背代码,要点:
- 递归
- 判断类型
- 检查环(也叫循环引用)
- 需要忽略原型
21. JS中值和地址的区别
- 像string bool number这些都是值
- 像存一些函数的变量 这些都是地址
- 通过typeof object判断是值还是地址
🈶22. 函数防抖和函数节流****
1. 背代码
```
冷却时间
// 节流(一段时间执行一次之后,就不执行第二次)
function throttle(fn, delay){
let canUse = true
return function(){
if(canUse){
fn.apply(this, arguments)
canUse = false
setTimeout(()=>canUse = true, delay)
}
}
}
const throttled = throttle(()=>console.log('hi'))
throttled()
throttled()
```
注意,有些地方认为节流函数不是立刻执行的,而是在冷却时间末尾执行的(相当于施法有吟唱时间),那样说也是对的。
1. 背代码
```
带着一起做
// 防抖(一段时间会等,然后带着一起做了)
function debounce(fn, delay){
let timerId = null
return function(){
const context = this
if(timerId){window.clearTimeout(timerId)}
timerId = setTimeout(()=>{
fn.apply(context, arguments)
timerId = null
},delay)
}
}
const debounced = debounce(()=>console.log('hi'))
debounced()
debounced()
```
🈶23. 如何实现数组去重***
1. 使用hash
unique = (array) => {
const hash = []
for(let i=0;i<array.length; i++){
hash[array[i]] = true
}
const result = []
for(let k in hash){
result.push(k)
}
return result
}
缺点:只支持数字或者字符串数组,如果数组里面有对象,比如 array = [{number:1}, 2],就会出错。
2. 使用set
[...new set(array)]
unique = (array) => {
return [...new Set(array)]
// 或者 return Array.from(new Set(array))
}
缺点:API 太新,旧浏览器不支持。
3. WeakMap 支持所有类型的去重
🈶24. 手写AJAX
- 什么是AJAX
Ajax是一种异步请求数据的web开发技术- 简单地说,在不需要重新刷新页面的情况下,Ajax 通过异步请求加载后台数据,并在网页上呈现出来。
- Ajax的目的是提高用户体验,较少网络数据的传输量。
1. 背代码,完整版
```
var request = new XMLHttpRequest()
request.open('GET', '/a/b/c?name=ff', true);
request.onreadystatechange = function () {
if(request.readyState === 4 && request.status === 200) {
console.log(request.responseText);
}};
request.send();
```
1. 背代码,简化版
```
var request = new XMLHttpRequest()
request.open('GET', '/a/b/c?name=ff', true)
request.onload = ()=> console.log(request.responseText)
request.send()
```
🈶26. 这段代码里的 this 是什么?
-
背代码
- fn()
this => window/global - obj.fn()
this => obj - fn.call(xx)
this => xx - fn.apply(xx)
this => xx - fn.bind(xx)
this => xx - new Fn()
this => 新的对象 - fn = ()=> {}
this => 外面的 this
- fn()
🈶27. 什么是 JSONP,什么是 CORS,什么是跨域?
- JSONP
- 优点:兼容IE、跨域
- 缺点:由于它是script标签,所以它拿不到状态码、拿不到header 、它不支持post , 只支持GET zhuanlan.zhihu.com/p/22600501
CORS方法 跨域资源共享
在被分享的server.js响应头里添加这个网站(要一模一样)
response.setHeader("Access-Control-Allow-Origin", "http://frank.com:9990")
developer.mozilla.org/zh-CN/docs/…
🈶28. async/await 怎么用,如何捕获异常?
- 为什么要await 为了让异步形式写成同步形式,让代码更像是同步的
🈶29. 如何用正则实现trim() ?
背代码
String.prototype.trim = function(){
return this.replace(/^\s+|\s+$/g, '')
}
//或者
function trim(string){
return string.replace(/^\s+|\s+$/g, '')
}
🈶30. 不用 class 如何实现继承?用 class 又如何实现?
1. 背代码,不用 class 这样实现
```
function Animal(color){
this.color = color
}
Animal.prototype.move = function(){} // 动物可以动
function Dog(color, name){
Animal.call(this, color) // 或者 Animal.apply(this, arguments)
this.name = name
}
// 下面三行实现 Dog.prototype.__proto__ = Animal.prototype
function temp(){}
temp.prototype = Animal.prototype
Dog.prototype = new temp()
Dog.prototype.constuctor = Dog // 这行看不懂就算了,面试官也不问
Dog.prototype.say = function(){ console.log('汪')}
var dog = new Dog('黄色','阿黄')
```
1. 背代码,用 class 就简单了
```
class Animal{
constructor(color){
this.color = color
}
move(){}
}
class Dog extends Animal{
constructor(color, name){
super(color)
this.name = name
}
say(){}
}
```
🈶31. 用mouse事件写一个可拖拽的div
32. 什么是DOM,什么是BOM
-
DOM(Document Object Model)是文档对象模型,
用途:就是把网页变成JS中的对象来进行增删改查操作
平时我们要操作DOM的话可以用
document.getElementById()来对它的各种属性进行修改 -
BOM(Browser Object Model)是浏览器对象模型 用途: 用JS前进后退操作地址栏
🈶33. 事件委托
-
错误版(但是可能能过)
ul.addEventListener('click', function(e){ if(e.target.tagName.toLowerCase() === 'li'){ fn() // 执行某个函数 } })bug 在于,如果用户点击的是 li 里面的 span,就没法触发 fn,这显然不对。
-
高级版
function delegate(element, eventType, selector, fn) { element.addEventListener(eventType, e => { let el = e.target while (!el.matches(selector)) { if (element === el) { el = null break } el = el.parentNode } el && fn.call(el, e, el) }) return element }思路是点击 span 后,递归遍历 span 的祖先元素看其中有没有 ul 里面的 li。