1.手写bind函数
es6:
Function.prototype.bind = function(context, ...args) {
var fn = this;
return function(...rest) {
return fn.apply(context,[...args, ...rest]);
}
}
es5:
// 定义这个方法为myBind
Function.prototype.myBind = function(thisArg) {
if (typeof this !== 'function') {
return;
}
var _self = this;
var args = Array.prototype.slice.call(arguments, 1) //从第二个参数截取
return function() {
return _self.apply(thisArg, args.concat(Array.prototype.slice.call(arguments))); // 注意参数的处理
}
}
2.手写new
function Otaku () { …… }
// 使用 new
var person = new Otaku(……);
// 使用 objectFactory
var person = objectFactory(Otaku, ……)
function objectFactory() {
var obj = new Object(),
var Constructor = [].shift.call(arguments);
// 本函数传入的第一个参数为构造函数
obj.__proto__ = Constructor.prototype;
Constructor.apply(obj, arguments);
return obj;
};
3.数组扁平化
1.递归
function flatten(arr) {
var res = [];
arr.forEach(item => {
if(Array.isArray(item)) {
res = res.concat(flatten(item));
} else {
res.push(item);
}
});
return res;
}
2.reduce
// 说白了还是在递归
function flatten(arr) {
return arr.reduce((result, item)=> {
return result.concat(Array.isArray(item) ? flatten(item) : item);
}, []);
}
3.toString & split或者join & split
function flatten(arr) {
return arr.toString().split(',').map(function(item) {
return Number(item);
})
}
// join的话,用join(',')替代toString(),parseInt替换Number就好。
4.concat
function flatten(arr) {
while(arr.some(item=>Array.isArray(item))) {
arr = [].concat(...arr);
}
return arr;
}
// concat每次都能处理一层,[].concat(1, 2, 3, [4, 5])会返回[1,2,3,4,5]
4.函数柯里化
法1:
function curry(fn) {
// 获取原函数的参数长度
const argLen = fn.length;
// 保存预置参数
const presetArgs = [].slice.call(arguments, 1)
// 返回一个新函数
return function(...args) {
// 新函数调用时会继续传参
const allArgs = [...presetArgs, ...args]
if (allArgs.length >= argLen) {
// 如果参数够了,就执行原函数
return fn.apply(this, allArgs)
} else {
// 否则继续柯里化
return curry.call(null, fn, ...allArgs)
}
}
}
总结:首先返回的是一个函数,这个函数的功能是,若能下一步调用出结果就出结果。否则,当做第一次柯里化的时候就带上了参数,供后面使用,每次创建新闭包,也有了新的闭包数据。
法2:
function curry(fn){
let judge = (...args) => {
if(args.length === fn.length) return fn(...args)
return (...arg) =>{judge(...args,...arg)}
}
return judge
}
第二种更牛逼,用第二种吧
function fn(a, b, c) {
return a + b + c;
}
var curried = curry(fn);
curried(1, 2, 3); // 6
curried(1, 2)(3); // 6
curried(1)(2, 3); // 6
curried(1)(2)(3); // 6
curried(7)(8)(9); // 24
5.手写promise.all
function PromiseAll(promiseArray) { //返回一个Promise对象
return new Promise((resolve, reject) => {
const result = []
let count = 0 //设置一个计数器
promiseArray.forEach((item,index) =>{
item.then(res =>{
count++
result[index] = res
if(count === promiseArr.length){
resolve(result)
}
}).catch(err =>{
reject(err)
})
})
})
}
6.手写instanceOf
function _instanceof(A, B) {
var O = B.prototype;
A = A.__proto__;
while (true) {
if (A === null)
return false;
if (O === A)
return true;
A = A.__proto__;
}
}
7.手写reduce
Array.prototype.myReduce = function (cb, initialValue) {
const array = this//获取数组
let acc = initialValue || array[0]//acc相当于pre
const startIndex = initialValue ? 0 : 1
for (let i = startIndex; i < array.length; i++) {
const cur = array[i]
acc = cb(acc, cur, i, array)
}
return acc
}