modify
This commit is contained in:
213
19-面试题积累/01-我的面试经历 by smyhvae.md
Normal file
213
19-面试题积累/01-我的面试经历 by smyhvae.md
Normal file
@@ -0,0 +1,213 @@
|
||||
|
||||
|
||||
|
||||
## 20180323
|
||||
|
||||
### 什么是闭包,闭包有什么作用。
|
||||
|
||||
### ES6的新特性有哪些。
|
||||
|
||||
作用域、函数扩展(扩展运算符、默认参数、箭头函数)、异步promise、模块化。
|
||||
|
||||
### 追问:const常量有什么作用?确定不能修改吗?修改之后会报错吗?你有没有试过?
|
||||
|
||||
当时我的答案是斩钉截铁地说不能改,其实我说错了。后来查了一下,准确答案是:
|
||||
|
||||
- 如果是值类型,值不可变
|
||||
|
||||
- 如果是引用类型,地址不可变
|
||||
|
||||
所以说,虽然我不能修改引用类型的指向,但是我可以修改引用类型里的属性值。
|
||||
|
||||
|
||||
参考链接:<https://segmentfault.com/q/1010000012836140?sort=created>
|
||||
|
||||
|
||||
### 追问:const的原理是什么?
|
||||
|
||||
|
||||
面试官问:如果你定义了const,什么是常量?是它的值还是引用?比如说,我定义了一个const 的array,那我能往里面插入数据吗?
|
||||
|
||||
|
||||
|
||||
|
||||
### 箭头函数和匿名函数有什么区别吗?
|
||||
|
||||
箭头函数和匿名函数有个明显的区别:箭头函数内部的this是词法作用域,由上下文确定。
|
||||
|
||||
普通函数的this指向是动态作用域;箭头函数的this指向是依据词法作用域。
|
||||
|
||||
|
||||
参考链接:<https://zhuanlan.zhihu.com/p/25093389>
|
||||
|
||||
|
||||
### 可以讲一下promise的状态吗?
|
||||
|
||||
|
||||
|
||||
|
||||
### 追问:如果我写setTimeout(0),再写一个promise,哪个先执行?
|
||||
|
||||
我回答错了。
|
||||
|
||||
正确答案是:任务队列可以有多个,promise的任务队列,优先级更高。具体答案还需要再仔细看看。
|
||||
|
||||
|
||||
### http有了解吗?
|
||||
|
||||
|
||||
- 可以讲一下它的握手过程吗?
|
||||
|
||||
- http的缓存有了解吗?
|
||||
|
||||
- get和post区别
|
||||
|
||||
|
||||
### 做过CDN吗?
|
||||
|
||||
答得不具体。
|
||||
|
||||
百度百科的解释是:其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定。
|
||||
|
||||
|
||||
### Vue相关
|
||||
|
||||
- vue的双向绑定怎么实现的?我是说怎么实现?
|
||||
|
||||
我当时是回答MVVM模式。其实还需要答出Object.defineProperty( )的细节。
|
||||
|
||||
|
||||
- Vue里还有什么呢?
|
||||
|
||||
数据驱动、组件化。
|
||||
|
||||
|
||||
### 事件绑定:onClick和addEventListener的区别
|
||||
|
||||
|
||||
|
||||
### 说一下DOM里的事件冒泡
|
||||
|
||||
|
||||
### 用Webpack做过哪些功能?
|
||||
|
||||
### 追问:ES6转成ES5,改动代码,发现页面自动刷新。你说一下整个流程。
|
||||
|
||||
问的是webpack 自动刷新的流程。我没回答好。
|
||||
|
||||
|
||||
### 追问:既然webpack可以用来配置服务器,如果我要联调,怎么办?
|
||||
|
||||
问:启动了webpack,就可以直接连接到后端吗?
|
||||
|
||||
|
||||
### 说一下跨域
|
||||
|
||||
|
||||
### gzip压缩有了解吗
|
||||
|
||||
### 你做过什么项目?说一下?
|
||||
|
||||
答:我做过电商网站。
|
||||
|
||||
追问:遇到过什么问题吗?
|
||||
|
||||
答:我遇到了性能的问题。
|
||||
|
||||
追问:那你说一下性能的问题
|
||||
|
||||
我就答出了性能相关的五大点。
|
||||
|
||||
|
||||
|
||||
### node和express有了解吗?
|
||||
|
||||
### 追问requireJS,是异步的吗?
|
||||
|
||||
是异步的。
|
||||
|
||||
|
||||
|
||||
### Vue你是怎么用的?是把所有的代码都写在一个页面里的吗
|
||||
|
||||
答:我是模块化写的。
|
||||
|
||||
问:怎么分类?
|
||||
|
||||
|
||||
追问:vuex的的作用
|
||||
|
||||
|
||||
|
||||
### 移动端的触摸事件了解吗?
|
||||
|
||||
- touchstart touchmove touchend touchcancel(touchcancel当触点由于某些原因被中断时触发)
|
||||
|
||||
- 模拟 swipe 事件:记录两次 touchmove 的位置差,如果后一次在前一次的右边,说明向右滑了。
|
||||
|
||||
### 移动端的浏览器和电脑浏览器的 touch事件,有区别吗?
|
||||
|
||||
|
||||
我说我没了解过。
|
||||
|
||||
追问:移动端默认会有0.2秒的延迟。
|
||||
|
||||
我后来查了一下:
|
||||
|
||||
点击延迟:是指移动端浏览器在 touchend 和 click 之间存在 300ms ~ 350ms 的延迟。
|
||||
|
||||
|
||||
为了判断用户是否是进行双击操作。因为移动端双击是放大文字的手势操作。
|
||||
|
||||
主要是从点击屏幕上的元素到触发元素的 click 事件,移动浏览器会有大约 300 毫秒的等待时间。这是因为浏览器想看看你是不是要进行双击(double tap)操作。
|
||||
|
||||
解决方法:
|
||||
|
||||
- 将click事件换成touch end事件
|
||||
|
||||
- FastClick:FastClick的实现原理是在检测到touchend事件的时候,会通过DOM自定义事件立即出发模拟一个click事件,并把浏览器在300ms之后真正的click事件阻止掉。
|
||||
|
||||
事件发生顺序:在移动端,手指点击一个元素,会经过:touchstart --> touchmove -> touchend --》click。
|
||||
|
||||
|
||||
### 如何自定义事件
|
||||
|
||||
自定义事件的代码如下:
|
||||
|
||||
|
||||
```javascript
|
||||
var myEvent = new Event('clickTest');
|
||||
element.addEventListener('clickTest', function () {
|
||||
console.log('smyhvae');
|
||||
});
|
||||
|
||||
//元素注册事件
|
||||
element.dispatchEvent(myEvent); //注意,参数是写事件对象 myEvent,不是写 事件名 clickTest
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### 说一下状态码
|
||||
|
||||
### 手机端的web开发,怎么和原生做交互?
|
||||
|
||||
|
||||
问:比如web网页,想调用手机的拍照功能,怎么做?再比如怎么分享到朋友圈?
|
||||
|
||||
|
||||
|
||||
### vue的生命周期,有了解吗
|
||||
|
||||
create和mount有什么区别吗
|
||||
|
||||
什么时候执行update
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
329
19-面试题积累/02-HTML和CSS相关.md
Normal file
329
19-面试题积累/02-HTML和CSS相关.md
Normal file
@@ -0,0 +1,329 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## HTML 相关
|
||||
|
||||
|
||||
### 你是如何理解 HTML 语义化的?
|
||||
|
||||
|
||||
**语义化**:指对文本内容的结构化(内容语义化),选择合乎语义的标签(代码语义化)。
|
||||
|
||||
|
||||
**举例**:段落用 p,边栏用 aside,主要内容用 main 标签。
|
||||
|
||||
|
||||
**好处:**
|
||||
|
||||
- 便于开发者阅读和维护
|
||||
|
||||
- 有利于SEO:让浏览器的爬虫和辅助技术更好的解析,
|
||||
|
||||
|
||||
**语义化标签介绍**:
|
||||
|
||||
在HTML5出来之前,我们习惯于用div来表示页面的章节或者不同模块,但是`div`本身是没有语义的。但是现在,HTML5中加入了一些语义化标签,来更清晰的表达文档结构。
|
||||
|
||||
20180322_1120.jpg
|
||||
|
||||
|
||||
|
||||
参考链接:
|
||||
|
||||
- [初探 · HTML5语义化](https://zhuanlan.zhihu.com/p/32570423)
|
||||
|
||||
|
||||
### meta viewport 是做什么用的,怎么写?
|
||||
|
||||
|
||||
|
||||
```html
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||
```
|
||||
|
||||
控制页面在移动端不要缩小显示。
|
||||
|
||||
|
||||
### canvas 元素是干什么的?
|
||||
|
||||
看 MDN 的 [canvas 入门手册](https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API)。
|
||||
|
||||
|
||||
|
||||
|
||||
## 说一下CSS盒模型
|
||||
|
||||
可以参考本人的另外一篇文章:[CSS盒模型及BFC](https://github.com/smyhvae/Web/blob/master/18/02-CSS%E7%9B%92%E6%A8%A1%E5%9E%8B%E5%8F%8ABFC.md)
|
||||
|
||||
|
||||
|
||||
### css reset 和 Normalize.css 有什么区别
|
||||
|
||||
> 此题考英文。
|
||||
|
||||
二者都是用来**统一**浏览器的默认样式:
|
||||
|
||||
- reset:重置。相对「暴力」,不管你有没有用,统统重置成一样的效果,且影响的范围很大,讲求跨浏览器的一致性。(一刀切)
|
||||
|
||||
- `Normalize.css` :标准化。相对「平和」,注重通用的方案,重置掉该重置的样式,保留有用的 user agent 样式,同时进行一些 bug 的修复,这点是 reset 所缺乏的。(去伪存真)
|
||||
|
||||
参考链接:
|
||||
|
||||
- [Normalize.css 与传统的 CSS Reset 有哪些区别?](https://p.baidu.com/question/ab496162636234613761335c00)
|
||||
|
||||
- [CSS3初始化代码Normalize.css中文版](http://www.bbsxiaomi.com/html_css/html5_css3/177.html)
|
||||
|
||||
- [谈谈一些有趣的 CSS 话题](https://github.com/chokcoco/iCSS)
|
||||
|
||||
- [前端面试之CSS总结(上)](https://segmentfault.com/a/1190000006890725)
|
||||
|
||||
|
||||
## 如何居中(必考)
|
||||
|
||||
|
||||
### 水平居中
|
||||
|
||||
1、**行内元素:**(文字、图片等水平居中)
|
||||
|
||||
给父亲设置:
|
||||
|
||||
|
||||
```
|
||||
text-align: center;
|
||||
|
||||
```
|
||||
|
||||
另外,**让文字的行高 等于 盒子的高度**,可以让单行文本垂直居中。
|
||||
|
||||
|
||||
2、**块级元素:**(让标准流中的盒子水平居中)
|
||||
|
||||
给父亲设置:
|
||||
|
||||
```
|
||||
//方式一
|
||||
margin: auto;
|
||||
|
||||
方式二
|
||||
margin: 0 auto;
|
||||
```
|
||||
|
||||
上面的代码, `margin: auto`相当于`margin: auto auto auto auto`。`margin: 0 auto`相当于`margin: 0 auto 0 auto`,四个值分别对应上右下左。
|
||||
|
||||
- 垂直方向:根据规范,margin-top: auto 和 margin-bottom: auto,其计算值为0。
|
||||
|
||||
- 水平方向:水平方向的 auto,其计算值取决于可用空间(**剩余空间**)。
|
||||
|
||||
参考链接:<https://www.zhihu.com/question/21644198/answer/22392394>
|
||||
|
||||
### 垂直居中/水平居中(元素的高度已知)
|
||||
|
||||
方法:绝对定位 + margin-top
|
||||
|
||||
如果盒子是绝对定位的,此时已经脱标了,`margin:auto`无效。如果还想让其居中(位于父亲的正中间),可以这样做:
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
<style>
|
||||
|
||||
|
||||
.parent {
|
||||
height: 300px; /*高度已知*/
|
||||
position: relative;
|
||||
border: 1px solid red;
|
||||
}
|
||||
|
||||
.child {
|
||||
width: 200px;
|
||||
height: 100px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin-left: -150px;
|
||||
margin-top: -50px;
|
||||
border: 1px solid green;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="parent">
|
||||
<div class="child">
|
||||
一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字一串文字
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
如上方代码所示,我们先让这个高度为100px的盒子,上边线居中,然后向上移动宽度的一半(50px),就达到了垂直居中的效果。水平居中的原理类似。
|
||||
|
||||
效果:
|
||||
|
||||
20180322_1843.png
|
||||
|
||||
### 垂直居中/水平居中(元素的高度未知)
|
||||
|
||||
**方法1:**模拟表格法
|
||||
|
||||
将父元素设置为display:table,然后将子元素也(就是要垂直居中显示的元素)设置为display:table-cell,然后加上vertical-align:middle来实现。
|
||||
|
||||
html代码:
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
<style>
|
||||
|
||||
|
||||
.parent {
|
||||
display: table;
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
border: 10px solid pink;
|
||||
|
||||
}
|
||||
|
||||
.child {
|
||||
display: table-cell;
|
||||
vertical-align: middle; /*来指定行内元素(inline)或表格单元格(table-cell)元素的垂直对齐方式。*/
|
||||
height: 200px; /*此处的宽高设置无效*/
|
||||
width: 200px;
|
||||
border: 10px solid blue;
|
||||
}
|
||||
|
||||
/*实现的效果:让单元格(.child)里的内容(.content)垂直居中*/
|
||||
.content {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border: 10px solid green;
|
||||
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="parent">
|
||||
<div class="child">
|
||||
<div class="content">
|
||||
<p>测试垂直居中效果测试垂直居中效果测试垂直居中效果测试垂直居中效果</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
效果:
|
||||
|
||||
20180322_1833.png
|
||||
|
||||
**方式二:**绝对定位 + `margin:auto`
|
||||
|
||||
```css
|
||||
.element {
|
||||
position: absolute;
|
||||
left: 0; top: 0; right: 0; bottom: 0;
|
||||
margin: auto; /* 有了这个就自动居中了 */
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
代码两个关键点:
|
||||
|
||||
- 上下左右均0位置定位;
|
||||
|
||||
- margin: auto
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
**方式三:**用绝对定位 + translate 位移来做
|
||||
|
||||
```css
|
||||
div {
|
||||
background-color: red;
|
||||
position: absolute; 绝对定位的盒子
|
||||
top: 50%; 首先,让上边线居中
|
||||
transform: translateY(-50%); 然后,利用translate,往上走自己宽度的一半【推荐写法】
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
**方式四:**flex 布局
|
||||
|
||||
```css
|
||||
.parent{
|
||||
display: flex;/*Flex布局*/
|
||||
display: -webkit-flex; /* Safari */
|
||||
align-items: center;/*设置子元素在侧轴方向上的布局*/
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
参考链接:
|
||||
|
||||
- [七种方式实现垂直居中](https://jscode.me/t/topic/1936)
|
||||
|
||||
- [margin:auto实现绝对定位元素的水平垂直居中](http://www.zhangxinxu.com/wordpress/2013/11/margin-auto-absolute-%E7%BB%9D%E5%AF%B9%E5%AE%9A%E4%BD%8D-%E6%B0%B4%E5%B9%B3%E5%9E%82%E7%9B%B4%E5%B1%85%E4%B8%AD/)
|
||||
|
||||
|
||||
## 选择器的优先级如何确定
|
||||
|
||||
- 选择器越具体,优先级越高。 #xxx 大于 .yyy
|
||||
|
||||
- 同样优先级,写在后面的覆盖前面的。
|
||||
|
||||
- color: red !important; 优先级最高。
|
||||
|
||||
|
||||
## BFC 是什么
|
||||
|
||||
|
||||
overflow:hidden :取消父子 margin 合并。 (另一种推荐做法:`padding-top: 0.1px;`)
|
||||
|
||||
|
||||
## 如何清除浮动
|
||||
|
||||
(1)overflow: hidden
|
||||
|
||||
(2).clearfix 清除浮动写在爸爸身上
|
||||
|
||||
```css
|
||||
.clearfix::after {
|
||||
content: '';
|
||||
display: block;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
/* 兼容 IE */
|
||||
.clearfix {
|
||||
zoom: 1;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 参考链接
|
||||
|
||||
- [互联网公司招聘启事的正确阅读方式](https://zhuanlan.zhihu.com/p/33998813)
|
||||
|
||||
|
||||
361
19-面试题积累/03-JS相关.md
Normal file
361
19-面试题积累/03-JS相关.md
Normal file
@@ -0,0 +1,361 @@
|
||||
|
||||
|
||||
## JS 有哪些数据类型
|
||||
|
||||
- 基本数据类型:string number bool undefined null
|
||||
|
||||
- 引用数据类型:object、symbol。
|
||||
|
||||
另外,object 包括:数组、函数、正则、日期等对象。NaN属于number类型。
|
||||
|
||||
注意,数据类型里,没有数组。因为数组属于object(一旦说数组、函数、正则、日期、NaN是数据类型,直接0分)。
|
||||
|
||||
|
||||
|
||||
## Promise 怎么使用
|
||||
|
||||
then:
|
||||
|
||||
```javascript
|
||||
$.ajax(...).then(成功函数, 失败函数)
|
||||
```
|
||||
|
||||
|
||||
|
||||
链式 then:
|
||||
|
||||
```javascript
|
||||
$.ajax(...).then(成功函数, 失败函数).then(成功函数2, 失败函数2)
|
||||
```
|
||||
|
||||
|
||||
如何自己生成 Promise 对象:
|
||||
|
||||
```javascript
|
||||
function xxx(){
|
||||
return new Promise(function(resolve, reject){
|
||||
setTimeout(()=>{
|
||||
resolve() 或者 reject()
|
||||
},3000)
|
||||
})
|
||||
}
|
||||
xxx().then(...)
|
||||
```
|
||||
|
||||
|
||||
## ajax手写
|
||||
|
||||
|
||||
|
||||
|
||||
```javascript
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open('POST', '/xxxx');
|
||||
xhr.onreadystatechange = function(){
|
||||
if(xhr.readyState === 4 && xhr.status === 200){
|
||||
console.log(xhr.responseText)
|
||||
}
|
||||
}
|
||||
xhr.send('a=1&b=2');
|
||||
|
||||
```
|
||||
|
||||
|
||||
## 闭包是什么
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
```javascript
|
||||
function fn1() {
|
||||
var a = 2
|
||||
|
||||
function fn2() {
|
||||
a++
|
||||
console.log(a)
|
||||
}
|
||||
return fn2;
|
||||
}
|
||||
|
||||
var f = fn1(); //执行外部函数fn1,返回的是内部函数fn2
|
||||
f() // 3 //执行fn2
|
||||
f() // 4 //再次执行fn2
|
||||
console.log(a); // 会报错:a is not defined
|
||||
|
||||
```
|
||||
|
||||
|
||||
参考链接:
|
||||
|
||||
- [JS 中的闭包是什么?](https://zhuanlan.zhihu.com/p/22486908)
|
||||
|
||||
|
||||
## 这段代码里的 this 是什么?
|
||||
|
||||
1、fn() 里面的 this 就是 window
|
||||
|
||||
2、fn() 是 strict mode,this 就是 undefined
|
||||
|
||||
3、a.b.c.fn() 里面的 this 就是 a.b.c
|
||||
|
||||
4、new F() 里面的 this 就是新生成的实例
|
||||
|
||||
5、() => console.log(this) ,这个this指的是外面的 this。
|
||||
|
||||
参考链接:
|
||||
|
||||
- [this 的值到底是什么?](https://zhuanlan.zhihu.com/p/23804247)
|
||||
|
||||
## 什么是立即执行函数?作用是?
|
||||
|
||||
|
||||
立即执行函数:
|
||||
|
||||
(1)声明一个匿名函数,(2)马上调用这个匿名函数。如下:
|
||||
|
||||
```javascript
|
||||
(function(a, b) {
|
||||
var name; //声明一个局部变量
|
||||
console.log("a = " + a);
|
||||
console.log("b = " + b);
|
||||
})(123, 456);
|
||||
```
|
||||
|
||||
|
||||
**作用:**创建一个独立的作用域,防止污染全局变量。
|
||||
|
||||
因为我们只能通过函数的形式声明一个局部变量。当有了ES6之后,我们可以通过let来定义一个局部变量:
|
||||
|
||||
|
||||
```javascript
|
||||
{
|
||||
let name
|
||||
}
|
||||
```
|
||||
|
||||
上面这段代码,就相当于立即执行函数。有了let,立即执行函数就毫无意义。
|
||||
|
||||
|
||||
参考链接:
|
||||
|
||||
## ES6 新特性
|
||||
|
||||
|
||||
## async/await 语法了解吗?目的是什么?
|
||||
|
||||
目的:把异步代码写成同步代码的形式。
|
||||
|
||||
|
||||
我们知道,promise是这样写的:
|
||||
|
||||
|
||||
```javascript
|
||||
let promise = new Promise((resolve, reject) => {
|
||||
//进来之后,状态为pending
|
||||
console.log('111'); //这一行代码是同步的
|
||||
//开始执行异步操作(这里开始,写异步的代码,比如ajax请求 or 开启定时器)
|
||||
if (异步的ajax请求成功) {
|
||||
console.log('333');
|
||||
resolve();//如果请求成功了,请写resolve(),此时,promise的状态会被自动修改为fullfilled
|
||||
} else {
|
||||
reject();//如果请求失败了,请写reject(),此时,promise的状态会被自动修改为rejected
|
||||
}
|
||||
})
|
||||
console.log('222');
|
||||
|
||||
//调用promise的then()
|
||||
promise.then(() => {
|
||||
//如果promise的状态为fullfilled,则执行这里的代码
|
||||
console.log('成功了');
|
||||
}
|
||||
, () => {
|
||||
//如果promise的状态为rejected,则执行这里的代码
|
||||
console.log('失败了');
|
||||
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
有了await之后,可以直接替换掉then。如下:
|
||||
|
||||
|
||||
```javascript
|
||||
function returnPromise(){
|
||||
return new Promise( function(resolve, reject){
|
||||
setTimeout(()=>{
|
||||
resolve('success')
|
||||
},3000)
|
||||
})
|
||||
}
|
||||
|
||||
returnPromise().then((result)=>{
|
||||
result === 'success'
|
||||
})
|
||||
|
||||
var result = await returnPromise()
|
||||
result === 'success'
|
||||
|
||||
```
|
||||
|
||||
## 如何实现深拷贝
|
||||
|
||||
### 方式一:JSON 来深拷贝
|
||||
|
||||
```javascript
|
||||
var a = {...};
|
||||
var b = JSON.parse(JSON.stringify(a)); //先将对象转成json字符串,然后再转成对象
|
||||
```
|
||||
|
||||
缺点:JSON 不支持函数、引用、undefined、RegExp、Date……
|
||||
|
||||
|
||||
### 方式二:递归拷贝
|
||||
|
||||
|
||||
```javascript
|
||||
function clone(object){
|
||||
var object2
|
||||
if(! (object instanceof Object) ){
|
||||
return object
|
||||
}else if(object instanceof Array){
|
||||
object2 = []
|
||||
}else if(object instanceof Function){
|
||||
object2 = eval(object.toString())
|
||||
}else if(object instanceof Object){
|
||||
object2 = {}
|
||||
}
|
||||
你也可以把 Array Function Object 都当做 Object 来看待,参考 https://juejin.im/post/587dab348d6d810058d87a0a
|
||||
for(let key in object){
|
||||
object2[key] = clone(object[key])
|
||||
}
|
||||
return object2
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## 如何实现数组去重
|
||||
|
||||
### 方式1:计数排序的逻辑(只能针对正整数)
|
||||
|
||||
|
||||
|
||||
|
||||
```javascript
|
||||
var a = [4,2,5,6,3,4,5]
|
||||
var hashTab = {}
|
||||
for(let i=0; i<a.length;i++){
|
||||
if(a[i] in hashTab){
|
||||
// 什么也不做
|
||||
}else{
|
||||
hashTab[ a[i] ] = true
|
||||
}
|
||||
}
|
||||
//hashTab: {4: true, 2: true, 5: true, 6:true, 3: true}
|
||||
console.log(Object.keys(hashTab)) // ['4','2','5','6','3']
|
||||
|
||||
```
|
||||
|
||||
### 方式二:set
|
||||
|
||||
|
||||
```javascript
|
||||
Array.from(new Set(a));
|
||||
```
|
||||
|
||||
|
||||
###方式三
|
||||
|
||||
|
||||
## 如何用正则实现 string.trim()
|
||||
|
||||
```javascript
|
||||
function trim(string) {
|
||||
return string.replace(/^\s+|\s+$/g, '')
|
||||
}
|
||||
```
|
||||
|
||||
## JS 原型是什么?
|
||||
|
||||
|
||||
|
||||
参考链接:
|
||||
|
||||
|
||||
- [什么是 JS 原型链?](https://zhuanlan.zhihu.com/p/23090041)
|
||||
|
||||
|
||||
|
||||
## ES 6 中的 class 了解吗?
|
||||
|
||||
|
||||
参考链接:
|
||||
|
||||
- <https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Classes>
|
||||
|
||||
|
||||
## 如何实现继承
|
||||
|
||||
- 构造函数
|
||||
|
||||
- 原型链
|
||||
|
||||
- extends
|
||||
|
||||
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
65
19-面试题积累/03-http.md
Normal file
65
19-面试题积累/03-http.md
Normal file
@@ -0,0 +1,65 @@
|
||||
|
||||
|
||||
## HTTP 状态码知道哪些?
|
||||
|
||||
301 和 302 的区别:
|
||||
|
||||
- 301 永久重定向,浏览器会记住(有缓存)
|
||||
|
||||
- 302 临时重定向(无缓存)
|
||||
|
||||
|
||||
## HTTP 缓存怎么做?
|
||||
|
||||
强缓存:
|
||||
|
||||
- **`Expires`**或**`Cache-Control`**
|
||||
|
||||
协商缓存:
|
||||
|
||||
- 第一对:`Last-Modified`、`If-Modified-Since`
|
||||
|
||||
- 第二对:`ETag`、`If-None-Match`
|
||||
|
||||
|
||||
## Cookie 是什么?Session 是什么?
|
||||
|
||||
### Cookie
|
||||
|
||||
- HTTP响应通过 Set-Cookie 设置 Cookie
|
||||
|
||||
- 浏览器访问指定域名是必须带上 Cookie 作为 Request Header
|
||||
|
||||
- Cookie 一般用来记录用户信息
|
||||
|
||||
### Session
|
||||
|
||||
- Session 是服务器端的内存(数据)
|
||||
|
||||
- session 一般通过在 Cookie 里记录 SessionID 实现
|
||||
|
||||
- SessionID 一般是随机数
|
||||
|
||||
|
||||
## LocalStorage 和 Cookie 的区别是什么?
|
||||
|
||||
- Cookie 会随请求被发到服务器上,而 LocalStorage 不会
|
||||
|
||||
- Cookie 大小一般4k以下,LocalStorage 一般5Mb 左右
|
||||
|
||||
## GET 和 POST 的区别是什么?
|
||||
|
||||
GET和POST本质上就是TCP链接,并无差别。但是由于HTTP的规定和浏览器/服务器的限制,导致他们在应用过程中体现出一些不同。
|
||||
|
||||
|
||||
需要注意的是,web 中的 get/post 只是 http 中的 get/post 的子集。http 中的 get 与 post 只是单纯的名字上的区别,get 请求的数据也可以放在 request body 中,只是浏览器没有实现它,但是 get 并不只是在 web 中使用
|
||||
|
||||
|
||||
参考链接:
|
||||
|
||||
- <http://www.cnblogs.com/zichi/p/5229108.html>
|
||||
|
||||
- <https://zhuanlan.zhihu.com/p/22536382>
|
||||
|
||||
|
||||
|
||||
360
19-面试题积累/04-变量提升的题目.md
Normal file
360
19-面试题积累/04-变量提升的题目.md
Normal file
@@ -0,0 +1,360 @@
|
||||
|
||||
|
||||
## 变量提升
|
||||
|
||||
先说三句总结性的话:
|
||||
|
||||
- let 的「创建」过程被提升了,但是初始化没有提升。
|
||||
|
||||
- var 的「创建」和「初始化」都被提升了。
|
||||
|
||||
- function 的「创建」「初始化」和「赋值」都被提升了。
|
||||
|
||||
### 变量提升的规律
|
||||
|
||||
在进入一个执行上下文后,先把 var 和 function 声明的变量前置,再去顺序执行代码。
|
||||
|
||||
PS:作用域分为全局作用域和函数作用域,用var声明的变量,只在自己所在的所用域有效。
|
||||
|
||||
我们举例来看看下面的代码。
|
||||
|
||||
**代码 1:**
|
||||
|
||||
```javascript
|
||||
console.log(fn);
|
||||
var fn = 1;
|
||||
|
||||
function fn() {
|
||||
}
|
||||
|
||||
console.log(fn);
|
||||
```
|
||||
|
||||
|
||||
相当于:
|
||||
|
||||
```javascript
|
||||
var fn = undefined;
|
||||
|
||||
function fn() {
|
||||
}
|
||||
|
||||
console.log(fn);
|
||||
fn = 1;
|
||||
console.log(fn);
|
||||
```
|
||||
|
||||
|
||||
打印结果:
|
||||
|
||||

|
||||
|
||||
**代码 2:**
|
||||
|
||||
```javascript
|
||||
console.log(i);
|
||||
for (var i = 0; i < 3; i++) {
|
||||
console.log(i)
|
||||
}
|
||||
```
|
||||
|
||||
相当于:
|
||||
|
||||
```javascript
|
||||
var i = undefined;
|
||||
|
||||
console.log(i);
|
||||
for (i = 0; i < 3; i++) {
|
||||
console.log(i);
|
||||
}
|
||||
```
|
||||
|
||||
打印结果:
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
**代码 3:**
|
||||
|
||||
```javascript
|
||||
var a = 1;
|
||||
|
||||
function fn() {
|
||||
a = 2;
|
||||
console.log(a)
|
||||
var a = 3;
|
||||
console.log(a)
|
||||
}
|
||||
|
||||
fn();
|
||||
console.log(a);
|
||||
```
|
||||
|
||||
相当于:
|
||||
|
||||
```javascript
|
||||
var a = undefined;
|
||||
|
||||
function fn() {
|
||||
var a
|
||||
|
||||
a = 2
|
||||
console.log(a)
|
||||
a = 3
|
||||
console.log(a)
|
||||
};
|
||||
|
||||
a = 1;
|
||||
fn();
|
||||
console.log(a);
|
||||
```
|
||||
|
||||
打印结果:
|
||||
|
||||

|
||||
|
||||
参考链接:<https://github.com/jirengu/javascript-tutorial>
|
||||
|
||||
|
||||
### 声明时的重名问题
|
||||
|
||||
假设`a`被声明为变量,紧接着`a`又被声明为函数,原则是:声明会被覆盖(先来后到,就近原则)。
|
||||
|
||||
PS:
|
||||
|
||||
- 如果`a`已经有值,再用 var 声明是无效的。
|
||||
|
||||
- 如果`a`已经有值,紧接着又被赋值,则**赋值会被覆盖**。
|
||||
|
||||
|
||||
举例1:
|
||||
|
||||
```javascript
|
||||
var fn; //fn被声明为变量
|
||||
function fn() {// fn被声明为function,就近原则
|
||||
|
||||
}
|
||||
|
||||
console.log(fn); //打印结果:function fn(){}
|
||||
|
||||
```
|
||||
|
||||
举例2:
|
||||
|
||||
```javascript
|
||||
function fn() {} //fn被声明为function,且此时fn已经被赋值,这个值就是function的对象
|
||||
|
||||
var fn; //fn已经在上一行被声明且已经有值, 再 var 无效,并不会重置为 undefined
|
||||
|
||||
console.log(fn) //打印结果:function fn(){}
|
||||
```
|
||||
|
||||
|
||||
既然再var无效,但是再function,是有效的:
|
||||
|
||||
|
||||
```javascript
|
||||
function fn() {} //fn被声明为function,且此时fn已经有值,这个值就是function的对象
|
||||
|
||||
function fn() { //此时fn被重复赋值,会覆盖上一行的值
|
||||
console.log('smyhvae');
|
||||
}
|
||||
console.log(fn)
|
||||
|
||||
```
|
||||
|
||||
打印结果:
|
||||
|
||||

|
||||
|
||||
### 函数作用域中的变量提升(两点提醒)
|
||||
|
||||
|
||||
**提醒1:**
|
||||
|
||||
在函数作用域也有声明提前的特性:
|
||||
|
||||
- 使用var关键字声明的变量,是在函数作用域内有效,而且会在函数中所有的代码执行之前被声明
|
||||
|
||||
- 函数声明也会在函数中所有的代码执行之前执行
|
||||
|
||||
|
||||
因此,在函数中,没有var声明的变量都会成为**全局变量**,而且并不会提前声明。
|
||||
|
||||
举例1:
|
||||
|
||||
```javascript
|
||||
var a = 1;
|
||||
|
||||
function foo() {
|
||||
console.log(a);
|
||||
a = 2; // 此处的a相当于window.a
|
||||
}
|
||||
|
||||
foo();
|
||||
console.log(a); //打印结果是2
|
||||
|
||||
```
|
||||
|
||||
上方代码中,foo()的打印结果是`1`。如果去掉第一行代码,打印结果是`Uncaught ReferenceError: a is not defined`
|
||||
|
||||
|
||||
**提醒2:**定义形参就相当于在函数作用域中声明了变量。
|
||||
|
||||
```
|
||||
|
||||
function fun6(e) {
|
||||
console.log(e);
|
||||
}
|
||||
|
||||
fun6(); //打印结果为 undefined
|
||||
fun6(123);//打印结果为123
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 其他题目
|
||||
|
||||
**20180321面试题:**
|
||||
|
||||
```javascript
|
||||
var a = 1;
|
||||
if (a > 0) {
|
||||
console.log(a);
|
||||
var a = 2;
|
||||
}
|
||||
console.log(a);
|
||||
|
||||
```
|
||||
|
||||
打印结果:
|
||||
|
||||
```
|
||||
1
|
||||
|
||||
2
|
||||
```
|
||||
|
||||
上方代码中,不存在块级作用域的概念。if语句中用var定义的变量,让然是全局变量。
|
||||
|
||||
顺便延伸一下,用let定义的变量,是在块级作用域内有效。
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
5
19-面试题积累/05-BAT爱考的JS面试题.md
Normal file
5
19-面试题积累/05-BAT爱考的JS面试题.md
Normal file
@@ -0,0 +1,5 @@
|
||||
|
||||
|
||||
|
||||
## this 在各个场景下的指向
|
||||
|
||||
16
19-面试题积累/函数.md
Normal file
16
19-面试题积累/函数.md
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
|
||||
```
|
||||
var arr = [1, 2, 3];
|
||||
|
||||
fun(arr);
|
||||
console.log(arr);
|
||||
|
||||
function fun(a) {
|
||||
a = [];
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
上方代码的打印结果是:[1,2,3]
|
||||
|
||||
35
19-面试题积累/异步.md
Normal file
35
19-面试题积累/异步.md
Normal file
@@ -0,0 +1,35 @@
|
||||
|
||||
|
||||
## 面试题
|
||||
|
||||
### 20180321面试题
|
||||
|
||||
```javascript
|
||||
console.log(1);
|
||||
|
||||
setTimeout(function () {
|
||||
console.log(2);
|
||||
}, 1000);
|
||||
|
||||
setTimeout(function () {
|
||||
console.log(3);
|
||||
}, 0);
|
||||
|
||||
console.log(4);
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 20180321面试题
|
||||
|
||||
```javascript
|
||||
var arr = [1, 2, 3];
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
setTimeout(function () {
|
||||
console.log(i);
|
||||
}, 0);
|
||||
}
|
||||
```
|
||||
|
||||
打印结果:3,3,3
|
||||
|
||||
21
19-面试题积累/清单.md
Normal file
21
19-面试题积累/清单.md
Normal file
@@ -0,0 +1,21 @@
|
||||
01.md
|
||||
|
||||
|
||||
|
||||
### CommonJS、RequireJS(AMD) SeaJS(CMD)区别
|
||||
|
||||
|
||||
|
||||
|
||||
### Webpack 打包
|
||||
|
||||
|
||||
### WebSocket
|
||||
|
||||
|
||||
### ES6
|
||||
|
||||
会 ES6 是应该的部分,不算加分项。
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user