Skip to content

Commit

Permalink
feat: update readme
Browse files Browse the repository at this point in the history
  • Loading branch information
biao.chen committed Aug 29, 2021
1 parent 0a90337 commit fb836e1
Show file tree
Hide file tree
Showing 2 changed files with 227 additions and 17 deletions.
30 changes: 13 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

## 简介

地址:[https://biaochenxuying.cn/](https://biaochenxuying.cn/)
<!-- 地址:[https://biaochenxuying.cn/](https://biaochenxuying.cn/) -->


> **芳华正茂始少年,时光正好,未来可期 !**
Expand All @@ -15,7 +15,7 @@

> 以最优惠的方式购买极客时间课程:https://github.com/biaochenxuying/preferential-courses ,涵盖了后端、架构、前端、移动、人工智能、大数据、产品、运营、运维、测试等
> 专注于挖掘优秀的前端开源项目,抹平你的前端信息不对称的项目:https://github.com/FrontEndGitHub/FrontEndGitHub
<!-- > 专注于挖掘优秀的前端开源项目,抹平你的前端信息不对称的项目:https://github.com/FrontEndGitHub/FrontEndGitHub -->


<!-- ## 分类
Expand All @@ -33,14 +33,13 @@
- [半小时硬核理财入门](https://github.com/biaochenxuying/blog/projects/9)
- [随笔](https://github.com/biaochenxuying/blog/projects/5) -->

## 专栏
<!-- ## 专栏
- [**掘金专栏**](https://juejin.im/user/591d6b4d0ce463006926ae40)
- [**掘金专栏**](https://juejin.im/user/591d6b4d0ce463006926ae40) -->

## 目录

- [简介](#简介)
- [专栏](#专栏)
- [目录](#目录)
- [文章](#文章)
- [Vue3.x](#vue3x)
Expand All @@ -61,13 +60,10 @@
- [性能优化](#性能优化)
- [VuePress & GitBook](#vuepress--gitbook)
- [半小时硬核理财入门](#半小时硬核理财入门)
- [学习资源](#学习资源)
- [计划](#计划)
- [webpack 原理及源码分析](#webpack-原理及源码分析)
- [Vue 原理及源码分析](#vue-原理及源码分析)
- [小程序入门到熟练](#小程序入门到熟练)
- [服务器](#服务器)
- [撩我](#撩我)


## 文章
Expand Down Expand Up @@ -207,13 +203,13 @@
- [2. 用钱生钱,谈谈我对财富自由的理解](https://github.com/biaochenxuying/blog/issues/82)
- 精彩待续 ...

### 学习资源
<!-- ### 学习资源
- [1. **150+ 本技术类常用电子书开源了,包括 前端、后端、数据结构与算法、计算机基础、设计模式、数据库等书籍**](https://github.com/biaochenxuying/awesome-books)
- [2. 极客时间上的《TypeScript 开发实战》课程资源,包含课件、思维导图、课程源代码](https://github.com/biaochenxuying/blog/tree/master/typescript-in-action)
- [3. 视频资料分享 - Vue、React、Node、MongoDB 全栈、打造商城系统、实战项目汇总](https://mp.weixin.qq.com/s/7f767Y5FHM9i2_GeUSz-Iw)
[⬆️ 返回顶部](#目录)
[⬆️ 返回顶部](#目录) -->

## 计划

Expand All @@ -240,7 +236,7 @@

[⬆️ 返回顶部](#目录)


<!--
## 服务器
笔者觉得每个开发者都应该拥有自己的网站和服务器,这可是很酷的事情,学习 Linux、跑跑脚本、建站、搭博客啥的都行啊。
Expand All @@ -259,12 +255,12 @@
> https://biaochenxuying.cn/
> https://www.kwgg2020.com/
> https://www.kwgg2020.com/ -->

<!--
[⬆️ 返回顶部](#目录) -->

[⬆️ 返回顶部](#目录)

## 撩我
<!-- ## 撩我
| 微信 | 公众号 |
Expand All @@ -277,10 +273,10 @@
![](https://upload-images.jianshu.io/upload_images/12890819-860e00b3a4b6c418.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
有需要的就来拿吧,**绝对免费,无套路获取**
有需要的就来拿吧,**绝对免费,无套路获取**。 -->


[⬆️ 返回顶部](#目录)
<!-- [⬆️ 返回顶部](#目录) -->


<!-- ## 打赏
Expand Down
214 changes: 214 additions & 0 deletions interview/fe-interview.md
Original file line number Diff line number Diff line change
Expand Up @@ -1736,8 +1736,88 @@ console.log(Object.prototype.toString.call(null)); // [object Null]
3. 如果你要传递的参数很多,则可以用数组将参数整理好调用 fn.apply(thisObj, [arg1, arg2 ...])
4. 如果你想生成一个新的函数长期绑定某个函数给某个对象使用,则可以使用 const newFn = fn.bind(thisObj); newFn(arg1, arg2...)
手写 bind
```js
Function.prototype.myBind = function(context, ...args) {
// 设置 fn 为调用 myCall 的方法
const fn = this
args = args ? args : []
// 设置返回的一个新方法
const result = function(...newFnArgs) {
// 如果是通过 new 调用的,绑定 this 为实例对象
if (this instanceof result) {
fn.apply(this, [...args, ...newFnArgs]);
} else { // 否则普通函数形式绑定 context
fn.apply(context, [...args, ...newFnArgs]);
}
}
// 绑定原型链
result.prototype = Object.create(fn.prototype);
// 返回结果
return result;
};
this.a = 1;
const fn = function() {
this.a = 2;
console.log(this.a);
}
fn.myBind(fn);
fn();
```
实现 apply
```js
Function.prototype.myApply = function (context, args) {
//这里默认不传就是给window,也可以用es6给参数设置默认参数
context = context || window
args = args ? args : []
//给context新增一个独一无二的属性以免覆盖原有属性
const key = Symbol()
context[key] = this
//通过隐式绑定的方式调用函数
const result = context[key](...args)
//删除添加的属性
delete context[key]
//返回函数调用的返回值
return result
}
```
实现 call
```js
//传递参数从一个数组变成逐个传参了,不用...扩展运算符的也可以用arguments代替
Function.prototype.myCall = function (context, ...args) {
//这里默认不传就是给window,也可以用es6给参数设置默认参数
context = context || window
args = args ? args : []
//给context新增一个独一无二的属性以免覆盖原有属性
const key = Symbol()
context[key] = this
//通过隐式绑定的方式调用函数
const result = context[key](...args)
//删除添加的属性
delete context[key]
//返回函数调用的返回值
return result
}
```
参考文章:
- [手写 bind, apply, call](https://juejin.cn/post/6844903891092389901)
- [call、apply、bind 的区别](https://www.jianshu.com/p/bbeadae6127e)
- [聊一聊 call、apply、bind 的区别](https://segmentfault.com/a/1190000012772040)
Expand Down Expand Up @@ -2193,6 +2273,9 @@ null 典型用法是: 
prototype 是函数对象上面预设的对象属性。
[深入JavaScript系列(六):原型与原型链](https://juejin.cn/post/6844903749345886216)
---
**实现 add(1)(2)(3) = 6**
Expand Down Expand Up @@ -3364,6 +3447,76 @@ document.addEventListener('scroll', better_scroll)
---
手写实现一个简单版本的 promise
```js
// 三个常量用于表示状态
const PENDING = 'pending'
const RESOLVED = 'resolved'
const REJECTED = 'rejected'
function MyPromise(fn) {
const that = this
this.state = PENDING
// value 变量用于保存 resolve 或者 reject 中传入的值
this.value = null
// 用于保存 then 中的回调,因为当执行完 Promise 时状态可能还是等待中,这时候应该把 then 中的回调保存起来用于状态改变时使用
that.resolvedCallbacks = []
that.rejectedCallbacks = []
function resolve(value) {
// 首先两个函数都得判断当前状态是否为等待中
if(that.state === PENDING) {
that.state = RESOLVED
that.value = value
// 遍历回调数组并执行
that.resolvedCallbacks.map(cb=>cb(that.value))
}
}
function reject(value) {
if(that.state === PENDING) {
that.state = REJECTED
that.value = value
that.rejectedCallbacks.map(cb=>cb(that.value))
}
}
// 完成以上两个函数以后,我们就该实现如何执行 Promise 中传入的函数了
try {
fn(resolve,reject)
}cach(e){
reject(e)
}
}
// 最后我们来实现较为复杂的 then 函数
MyPromise.prototype.then = function(onFulfilled,onRejected){
const that = this
// 判断两个参数是否为函数类型,因为这两个参数是可选参数
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v => v;
onRejected = typeof onRejected === 'function' ? onRejected : e => throw e;
// 当状态不是等待态时,就去执行相对应的函数。如果状态是等待态的话,就往回调函数中 push 函数
if(this.state === PENDING) {
this.resolvedCallbacks.push(onFulfilled)
this.rejectedCallbacks.push(onRejected)
}
if(this.state === RESOLVED) {
onFulfilled(that.value)
}
if(this.state === REJECTED) {
onRejected(that.value)
}
}
```
---
#### ES6+ 面试知识文章
- [那些必会用到的 ES6 精粹](https://github.com/biaochenxuying/blog/issues/1)
Expand Down Expand Up @@ -3651,6 +3804,56 @@ Vuex
![Vuex](https://upload-images.jianshu.io/upload_images/12890819-a4909259bd32ae9c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
---
在 Vue 2 的实现中,在组件初始化阶段把数据变成响应式时,遇到子属性仍然是对象的情况,会递归执行 Object.defineProperty 定义子对象的响应式;而在 Vue 3 的实现中,只有在对象属性被访问的时候才会判断子属性的类型来决定要不要递归执行 reactive,这其实是一种延时定义子对象响应式的实现,在性能上会有一定的提升。
---
涉及面试题:Proxy 可以实现什么功能?
在 Vue3.0 中将会通过 Proxy 来替换原本的 Object.defineProperty 来实现数据响应式。 Proxy 是 ES6 中新增的功能,它可以用来自定义对象中的操作。
```js
const p = new Proxy(target, handler)
```
target 代表需要添加代理的对象,handler 用来自定义对象中的操作,比如可以用来自定义 set 或者 get 函数。
接下来我们通过 Proxy 来实现一个数据响应式
```js
let onWatch = (obj, setBind, getLogger) => {
let handler = {
get(target, property, receiver) {
getLogger(target, property)
return Reflect.get(target, property, receiver)
},
set(target, property, value, receiver) {
setBind(value, property)
return Reflect.set(target, property, value)
}
}
return new Proxy(obj, handler)
}
let obj = { a: 1 }
let p = onWatch(
obj,
(v, property) => {
console.log(`监听到属性${property}改变为${v}`)
},
(target, property) => {
console.log(`'${property}' = ${target[property]}`)
}
)
p.a = 2 // 监听到属性a改变
p.a // 'a' = 2
```
#### Vue 经典面试相关文章
- [Vue 生命周期](https://www.jianshu.com/p/304a44f7c11b)
Expand Down Expand Up @@ -3763,6 +3966,12 @@ GET 和 POST 能做的事情是一样一样的。你要给 GET 加上 request bo
- GET 和 POST 本质上就是 TCP 链接,并无差别。但是由于 HTTP 的规定和浏览器/服务器的限制,导致他们在应用过程中体现出一些不同。
- [关于三次握手和四次挥手,面试官想听到怎样的回答?](https://juejin.cn/post/6978733203062915103)
- [跟着动画来学习TCP三次握手和四次挥手](https://juejin.cn/post/6844903625513238541)
---
**HTTP 中 GET 与 POST 的区别**
Expand Down Expand Up @@ -3826,6 +4035,11 @@ Last-Modified:请求对象最后一次的修改时间,用来判断缓存是
If-Modified-Since:客户端发送请求附带的信息,指浏览器缓存请求对象的最后修改日期,用来和服务器端的 Last-Modified 做比较。
[一文读懂前端缓存(好文)](https://juejin.cn/post/6844903747357769742)
---
**说一下 HTTP 协议头字段说上来几个,是否尽可能详细的掌握 HTTP 协议。**
Expand Down

0 comments on commit fb836e1

Please sign in to comment.