1. new 的原始碼實現
function Student() {
this.age = 40
}
Student.prototype.say = function () {}
var s = new Student()
function myNew(constructor, ...args) {
let obj = {}
constructor.apply(obj, args)
// 3 核心程式碼
obj.__proto__ = constructor.prototype
// 4
return obj
}
複製程式碼
2. 防抖與節流
const debounce = (fn,delay) => {
let timer = null
return (...args) => {
clearInterval(timer)
timer = setTimeout(() => {
fn.apply(this,...args)
},delay)
}
}
const throttle = (fn,delay) => {
let flag = true
return (...args) => {
if(!flag) return
flag = false
setTimeout(() => {
fn.apply(this,...args)
flag = true
},delay)
}
}
複製程式碼
3. 深拷貝
let obj = {
a: 1,
field4: {
child: 'child',
child2: {
child2: 'child2'
}
}
}
function clone(target) {
if (typeof target === 'object') {
let cloneTarget = {}
for (const key in target) {
cloneTarget[key] = clone(target[key])
}
return cloneTarget
} else{
return target
}
}
var obj1 = clone(obj)
obj1.field4.child2.child2 = '7777'
console.log(obj)
console.log(obj1)
複製程式碼
4. 實現event(設計模式訂閱釋出)
class EventEmitter {
constructor() {
this._events = {}
}
emit(type,...args) {
let handle = this._events[type]
if(!handle) {
return false
}
if(Array.isArray(handle)) {
for(let i = 0;i < handle.length;i++) {
handle[i].call(this,...args)
}
} else {
handle.call(this,...args)
}
}
on(type,fn) {
let handle = this._events[type]
if (typeof fn !== 'function') {
return null
}
if(!handle) {
this._events[type] = fn
} else {
this._events[type] = [].concat(this._events[type],fn)
}
}
off(type,fn) {
if(fn === undefined) {
this._events[type] = []
} else {
this._events[type] = this._events[type].filter(f => f !== fn)
}
}
once(type,fn) {
this._events[type] = fn
}
}
複製程式碼
5. object.create
function create(proto) {
function F() {}
F.prototype = proto
return new F()
}
複製程式碼
6. promise原生實現
class Promise {
constructor (fn) {
this.state = 'pending'
this.value = undefined
this.reason = undefined
let resolve = value => {
if (this.state === 'pending') {
this.value = value
this.state = 'fulfilled'
}
}
let reject = value => {
if (this.state === 'pending') {
this.value = value
this.state = 'rejected'
}
}
try {
fn(resolve, reject)
}catch (error){
reject(error)
}
}
then (onFulfilled, onRejected) {
switch (this.state) {
case 'fulfilled':
onFulfilled()
break;
case 'rejected':
onRejected()
break;
}
}
}
let pro = new Promise()
複製程式碼
7. 原生ajax實現
let xhr = new XMLHttpRequest()
xhr.setRequestHeader("Content-Type", "application/json");
xhr.open(method,url,async)
xhr.send(data)
xhr.onreadystatechange = () => {
if(xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText)
}
}
function ajax(options) {
const url = options.url
const method = options.method.toLocaleLowerCase() || 'get'
const async = options.async
const data = options.data
const xhr = new XMLHttpRequest() || new ActiveXObject('Microsoft','XMLHTTP')
if(options.timeout && options.timeout > 0) {
xhr.timeout = options.timeout
}
return new Promise((resolve,reject) => {
xhr.ontimeout = () => reject && reject('請求超時')
xhr.onreadystatechange = () => {
if(xhr.readyState === 4) {
if(xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) {
resolve(xhr.responseText)
} else {
reject && reject()
}
}
}
xhr.onerror = (err) => {
return reject && reject(err)
}
let paramArr = []
let encodeData
if(data instanceof Object) {
for (let key in data) {
paramArr.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]))
}
encodeData = paramArr.join('&')
}
if (method === 'get') {
const index = url.indexOf('?')
if(index === -1) url += "?"
else if(index !== url.length -1) url += "&"
url += encodeData
}
xhr.open(method,url,async)
if(method === 'get') {
xhr.send(null)
} else {
xhr.setRequestHeader('Content-type','applicaton/x-www-form-urlencoded;chatset:utf-8')
xhr.send(encodeData)
}
})
}
複製程式碼
8. 路由
class Route {
constructor() {
this.routes = {}
this.currentHash = ''
this.freshRoute = this.freshRoute.bind()
window.addEventListener('load',this.freshRoute,false)
window.addEventListener('hashchange',this.freshRoute,false)
}
storeRoute(path,cb) {
this.routes[path] = cb || function () {}
}
freshRoute () {
this.currentHash = location.hash.slice(1) || '/'
this.routes[this.currentHash]()
}
}
複製程式碼
9. 預編譯
# 預編譯 四部曲 發生在函式執行之前
1. 建立AO物件
2. 找形參和變數宣告,將變數申明和引數作為AO屬性名,值為undefined
3. 將實參值和形參值統一
4. 在函式體裡找函式申明,將函式申明作為AO物件屬性名,值賦予函式體
# 預編譯也發生在全域性
1. 建立GO物件
2. 找形參和變數宣告,將變數申明和引數作為GO屬性名,值為undefined
3. 在全域性裡找函式申明,將函式申明作為GO物件屬性名,值賦予函式體
先找AO,再找GO
複製程式碼
10. 函式柯里化
function add() {
var _args = Array.prototype.slice.call(arguments);
var _adder = function() {
_args.push(...arguments);
return _adder;
};
_adder.toString = function () {
return _args.reduce(function (a, b) {
return a + b;
});
}
return _adder;
}
const a = add(1)(2)(3)()
console.log(a)
function curry(fn, args) {
var length = fn.length;
args = args || [];
return function() {
var _args = args.slice(0),
arg, i;
for (i = 0; i < arguments.length; i++) {
arg = arguments[i];
_args.push(arg);
}
if (_args.length < length) {
return curry.call(this, fn, _args);
}
else {
return fn.apply(this, _args);
}
}
}
var fn = curry(function(a, b, c) {
console.log([a, b, c]);
});
複製程式碼
11. instanceof實現
function instance_of(L,R) {
var O = R.prototype
L = L.__proto__;
while(true) {
if (L === null) return false
if (L === O) {
return true
}
L = L.__proto__
}
}
複製程式碼
koa洋蔥模型
let middleWare1 = async function(ctx,next) {
console.log(1)
await next()
console.log(2)
}
let middleWare2 = async function(ctx,next) {
console.log(3)
await next()
console.log(4)
}
let middleWares = [middleWare1,middleWare2]
run()
function run() {
const dispatch = (index) => {
const fn = middleWares[index]
// 處理 next 讓他去到下一個中介軟體
fn({},() => {
dispatch(index + 1)
})
}
dispatch(0)
}
複製程式碼
redux 中介軟體
const mid1 = next => action => {
console.log(1)
next()
console.log(2)
}
const mid2 = next => action => {
console.log(3)
next()
console.log(4)
}
const mids = [mid1,mid2]
let fn1 = str => str.split('')
let fn2 = str => str.toLocaleLowerCase()
function compose(...funcs) {
if (funcs.length === 0) {
return arg => arg
}
if (funcs.length === 1) {
return funcs[0]
}
return funcs.reduce((a, b) => (...args) => a(b(...args)))
}
let opt = compose(fn1,fn2)
const chain = compose(...mids)
let nbDispatch = chain(() => [
console.log('我是最原始的dispatch')
])
nbDispatch()
複製程式碼
redux-thunk
function createThunkMiddleware(extraArgument) {
return ({ dispatch, getState }) => (next) => (action) => {
if (typeof action === 'function') {
return action(dispatch, getState, extraArgument);
}
return next(action);
};
}
複製程式碼
promisify 的實現
function promisify(fn) {
return function(...args) {
return new Promise((resolve, reject) => {
fn(...args, (err, data) => {
if(err) {
reject(err);
}
resolve(data)
})
})
}
}
複製程式碼