1. new
function myNew(P) {
let obj = {}
let args = [...arguments].slice(1)
obj.__proto__ = P.prototype
P.prototype.constructor = P
P.apply(obj, args)
return obj
}
function _new(fn, ...arg) {
const obj = Object.create(fn.prototype)
const ret = fn.apply(obj, arg)
return ret instanceof Object ? ret : obj
}
2. instanceof
function instanceOf(left, right) {
let leftValue = left.__proto__
let rightValue = right.prototype
while (true) {
if (leftValue === null) {
return false
}
if (leftValue === rightValue) {
return true
}
leftValue = leftValue.__proto__
}
}
3. call
Function.prototype.myCall = function(content = window) {
if (typeof this !== 'function') {
throw new TypeError('Error')
}
content.fn = this
let args = [...arguments].slice(1)
let result = content.fn(...args)
delete content.fn
return result
}
4. apply
Function.prototype.myApply = function(content = window) {
if (typeof this !== 'function') {
throw new TypeError('Error')
}
content.fn = this
let result
if (arguments[1]) {
result = content.fn(...arguments[1])
} else {
result = content.fn()
}
delete content.fn
return result
}
5. bind
Function.prototype.myBind= function(content) {
if (typeof this !== 'function') {
throw new TypeError('Error')
}
let _this = this
let args = [...arguments].slice(1)
return function F() {
if (this instanceof F) {
return new _this(...args, ...arguments)
} else {
return _this.apply(content, args.concat(...arguments))
}
}
}
6. 深拷贝
function deepClone(obj) {
let result = Array.isArray(obj) ? [] : {}
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
if (typeof obj[key] === 'object' && obj[key] !== null) {
result[key] = deepClone(obj[key])
} else {
result[key] = obj[key]
}
}
}
return result
}
7. 防抖/节流
function debounce(func, delay) {
let timeout
return function() {
clearTimeout(timeout)
timeout = setTimeout(() => {
func.apply(this, arguments)
}, delay)
}
}
function throttle(func, delay) {
let prev = Date.now()
return function() {
let now = Date.now()
if (now - prev >= delay) {
func.apply(this, arguments)
prev = Date.now()
}
}
}
function throttle2(func, delay) {
let run = true
return function() {
if (!run) return
run = false
setTimeout(() => {
func.apply(this, arguments)
run = true
}, delay)
}
}
8. Promise
class MyPromise {
constructor(executor) {
this.status = 'pending'
this.value = undefined
this.reason = undefined
this.resolveCallbacks = []
this.rejectCallbacks = []
const resolve = value => {
if (this.status === 'pending') {
this.status = 'fulfilled'
this.value = value
this.resolveCallbacks.forEach(fn => fn())
}
}
const reject = reason => {
if (this.status === 'pending') {
this.status = 'rejected'
this.reason = reason
this.rejectCallbacks.forEach(fn => fn())
}
}
try {
executor(resolve, reject)
} catch (error) {
reject(error)
}
}
then(onFulfilled, onRejected) {
if (this.status === 'fulfilled') {
onFulfilled(this.value)
} else if (this.status === 'rejected') {
onRejected(this.reason)
} else if (this.status === 'pending') {
this.resolveCallbacks.push(() => {
onFulfilled(this.value)
})
this.rejectCallbacks.push(() => {
onRejected(this.reason)
})
}
}
static all(promiseArr) {
return new Promise((resolve, reject) => {
let result = []
promiseArr.forEach((promise, index) => {
promise.then(val => {
result[index] = val
if (result.length === promiseArr.length) {
resolve(result)
}
}, reject)
})
})
}
static race(promiseArr) {
return new Promise((resolve, reject) => {
promiseArr.forEach(promise => {
promise.then(val => {
resolve(val)
}, reject)
})
})
}
}
9. 柯里化
function Currie(...nums) {
let arrs = [...nums]
function Add(...nums) {
arrs.push(...nums)
return Add
}
Add.toString = () => arrs.reduce((a, b) => a + b)
return Add
}
10. 数组乱序
function shuffle(arr) {
for (var i = 0; i < arr.length - 1; i++) {
let j = parseInt(Math.random() * (arr.length - 1))
[arr[i], arr[j]] = [arr[j], arr[i]]
}
return arr
}
11. 数组快速排序
function quickSort(arr) {
if (arr.length <= 1) return arr
let pivotIndex = Math.floor(arr.length / 2)
let pivot = arr.split(pivoIndex, 1)[0]
let left = []
let right = []
for (var i = 0; i < arr.length; i++) {
if (arr[i] < pivot) {
left.push(arr[i])
} else {
right.push(arr[i])
}
}
return quickSort(left).concat([pivot], quickSort(right))
}
12. Event Bus
class Bus {
constructor() {
this.callbacks = {}
}
$on(name, fn) {
this.callbacks[name] = this.callbacks[name] || []
this.callbacks[name].push(fn)
}
$emit(name, args) {
if (this.callbacks[name]) {
this.callbacks[name].forEach(cb => cb(args))
}
}
}
Vue.prototype.$bus = new Bus()
this.$bus.$on('foo', handle)
this.$bus.$emit('foo')