前端复习-手撕代码

  1. 数组扁平化
[1, 3, [5, 2], [2, 3, [4, 5]]]------->[1, 3, 5, 2, 2, 3, 4, 5]
// 1. 递归
function flat(arr) {
	let res = []
	for (let a of arr) {
		if (Array.isArray(a)) {
			res = res.concat(flat(a))
		} else {
			res.push(a)
		}
	}
	return res
}

// 2. 如果元素都是数字,可以使用toString
function flat2(arr) {
	return arr.toString().split(',').map(e => parseInt(e))
}

// 3. 利用扩展运算符和concat
// arrayObject.concat(arrayX,arrayX,......,arrayX)
function flat3(arr) {
	while(arr.some( item => Array.isArray(item) )){
		arr = [].concat(...arr);
	}
	return arr;
}

// 4. 利用 reduce
function flatten(arr) {
	return arr.reduce((res,next) =>{
		return res.concat(Array.isArray(next)? flatten(next) : next);
	}, []);
}

  1. bind
Function.prototype.bind = function(context, ...args) {
	let _this = this
	return function() {
		return _this.apply(context, args)
	}
}
  1. curry
// 柯里化函数
const curry = (fn) => {
	// 函数需要的参数数量
	let n = fn.length
	return function curriedFn(...args) {
		if (args.length < n) {
			return function(...currArg) {
				return curriedFn.apply(null, args.concat(currArg))
			}
		}
		return fn.apply(null, args)
	}
};
  1. Promise
function Promise(executor) {
	this.status = 'pending'
	this.successVal = undefined
	this.errorReason = undefined
	// 定义异步未执行的then上的方法
	this.onFulfilledCallbacks = []
	this.onRejectedCallbacks = []
	// 保证this指向
	let that = this

	function resolve(val) {
		if (that.status === 'pending') {
			that.status = 'fulfilled'
			that.successVal = val
			that.onFulfilledCallbacks.forEach(fn => fn())
		}
	}
	function reject(reason) {
		if (that.status === 'pending') {
			that.status = 'reject'
			that.errorReason  = reason
			that.onRejectedCallbacks.forEach(fn => fn())
		}
	}
	try {
		executor(resolve, reject)
	} catch(e) {
		reject(e)
	}
}

function resolvePromise(promise2, x, resolve, reject) {
	// 防止循环引用
	if (x === promise2) {
		reject(new TypeError('...'))
	}
	
	// 防止多次调用
	let called
	
	// x不是null且x不是对象或者函数
	if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
		try {
			// 规定要有这个方法
			let then = x.then
			if (typeof then === 'function') {
				then.call(x, y => {
					if (called) return
					called = true

					resolvePromise(promise2, y, resolve, reject)
				}, err => {
					if (called) return
					called = true
					reject(err)
				})
			} else {
				resolve(x)
			}
		} catch(e) {
			if (called) return
			called = true
			reject(e)
		}
	} else {
		resolve(x)
	}
}

Promise.prototype.then = function(onFulfilled, onRejected) {
	onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val
	onRejected = typeof onRejected === 'function' ? onRejected : error => {throw error}
	let that = this

	let promise2 = new Promise(function(resolve, reject) {
		// 判断状态
		if (that.status === 'fulfilled') {
			let x = onFulfilled(that.successVal)
			resolvePromise(promise2, x, resolve, reject)
		}
		if (that.status === 'rejected') {
			let x = onRejected(that.errorReason)
			resolvePromise(promise2, x, resolve, reject)
		}
		if (that.status === 'pending') {
			that.onFulfilledCallbacks.push(() => {
				let x = onFulfilled(that.successVal)
				resolvePromise(promise2, x, resolve, reject)
			})
			that.onRejectedCallbacks.push(() => {
				let x = onRejected(that.errorReason)
				resolvePromise(promise2, x, resolve, reject)
			})
		}
	})
	return promise2
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值