-
1、偏函数的理解,以及实现。
概念:理解偏函数的意思,固定函数的一个或多个参数
从实现来讲可以分为这几个步骤:
首先我们一般是做有占位符的偏函数,意思是固定某些特定位置的参数
循环接收参数的的数组,小于fn的length,push上占位符。
返回一个函数,在返回函数中定义一个初始的变量 index = 0
再次循环 传入的参数 arg ,接收新的参数 newArg,如果arg[i] === 占位符 index++ arg[i] = newArg[index++]
循环结束后 return fn.apply(this,arg)
-
2、函数柯里化的实现,理解。
把多参数通过闭包转化为单一参数,递归调用,返回一个函数。
1、需要传入一个函数
2、定义一个函数,返回这个函数,在这个函数中接受参数
3、判断传入的参数的长度是否等于传入函数的长度
4、如果长度相等 返回这个函数同时把函数执行,传入参数。
5、否则在返回一个新函数,接收新参数。
6、在返回定义的函数递归调用,传入参数。
-
3、数组去重的几种方法,以及统计字符串字符出现的次数。
-
4、数组交并差的方法。
-
5、Promise的理解以及一些实现, then,catch,resolve,reject,finally,all,race
-
6、new的实现理解。
1、偏函数的理解,以及实现。
/*
function add (a,b){
return a + b + this.value
}
var value = 'window'
// var fn1 = add.bind(null, 1)
var fn1 = partial(add,1) // 2obj
var obj = {
value: 'obj',
fn1:fn1
}
console.log(obj.fn1(1))
function partial(fn){
var arg = [].slice.call(arguments,1)
return function(){
var newArg = arg.concat([].slice.call(arguments))
return fn.apply(this, newArg)
}
} */
// console.log({}.toString.call(Symbol('1')).slice(8, -1).toLowerCase())
// 具有占位符的偏函数的实现 '_'
// ES5
/* function partail(fn){
var args = [].slice.call(arguments,1)
for(let i=args.length
args.push('_')
}
return function(){
var newArg = [].slice.call(arguments)
var index = 0
for(let i = 0
if(args[i] === '_'){
args[i] = newArg[index++]
}
}
return fn.apply(this, args)
}
}
function add(a,b,c){
return a+b+c
}
var fn1 = partail(add,'_',1,'_')
console.log(fn1(2,1)) */
// ES6 偏函数
/*
const partail = (fn,...args)=>{
let startNum = 0
return (...newArg)=>{
newArg.forEach(item=>{
let index = args.findIndex(res=>res==='_')
if (index<0) return
args[index] = item
startNum++
})
if(startNum<newArg.length){
newArg = newArg.slice(startNum,newArg.length)
}
return fn.apply(this, [...args,...newArg])
}
}
function add(a,b,c){
return a+b+c
}
var fn1 = partail(add,'_',1,'_')
console.log(fn1(2,3)) */
2、函数柯里化的实现,理解。
// add(1)(2)(3) === 6
// add(1,2,3) === 6
// add(1,2)(3) === 6
/* const addNum = (a,b,c)=>a+b+c
// ES6的一种方法
const curry = (fn)=>{
if(fn.length === 1) return fn
const next = (...arg)=>{
if(arg.length === fn.length){
return fn(...arg)
} else{
return (...arg1)=>{
return next(...arg,...arg1)
}
}
}
return next
}
3、数组去重的几种方法,以及统计字符串字符出现的次数。
// 数组去重的几种方法,由简单入难点。
// const arg = [1,2,3,1,2];
// const arg1 = [
// {
// name: 1,
// },
// 2,3,
// '2',
// {
// name: 1
// }
// ]
// 使用循环解决 包含引用数据类型
// const uniArr = (arg)=>{
// let temp = [];
// for(let i=0;i<arg.length;i++){
// if(temp.indexOf(JSON.stringify(arg[i]))<0){
// temp.push(JSON.stringify(arg[i]))
// }
// }
// return temp.map(item=>JSON.parse(item))
// }
// 最方便的es6的new Set()
// const uniArr = (arg)=>{
// return [...new Set(arg.map(v=>JSON.stringify(v)))].map(v=>JSON.parse(v))
// }
// 对象的key唯一这个属性 但是无法区分出来字符串和数字
// const uniArr = (arg)=>{
// const temp = {};
// for(v of arg){
// if(!temp.hasOwnProperty(JSON.stringify(v))){
// temp[v] = v
// }
// }
// return Object.values(temp)
// }
// 使用reduce方法
// const uniArr = (arr)=>{
// return arr.reduce((total,item)=>{
// if(!total.includes(JSON.stringify(item))){
// return total.concat(JSON.stringify(item))
// }else{
// return total.map(v=>JSON.parse(v))
// }
// },[])
// }
// console.log(uniArr(arg1))
// 扩展统计字符串中某个字符出现的次数 // 出现最高次数的排在前面
// const str = 'I Love China,go for it!'
// const count = (arg)=>{
// let tempObj = arg.split('').reduce((total,current)=>{
// total[current] ? total[current]++: total[current] = 1
// return total
// },{})
// let tempArr = []
// for(i in tempObj){
// tempArr.push({key: i,value:tempObj[i]})
// }
// const sortArr = tempArr.sort((a,b)=>-a.value+b.value);
// return sortArr
// }
// console.log(count(str))
// 数组的交并差的处理
// const arr1 = [1,2,3,{name:1},'22'];
// const arr2 = [2,{name:1},'2'];
/* const sameArr = (arg1,arg2)=>{
let temp = []
arg1.forEach(item=>{
if(arg2.map(v=>JSON.stringify(v)).includes(JSON.stringify(item))){
temp.push(item)
}
})
return temp
} */
// 可以
// const sameArr = (arg1,arg2)=>{
// return arg1.filter(item=>arg2.map(v=>JSON.stringify(v)).includes(JSON.stringify(item)))
// }
// 使用new Set 来处理
// const sameArr = (arg1,arg2)=>{
// return arg1.filter(item=> new Set(arg2.map(v=>JSON.stringify(v))).has(JSON.stringify(item)))
// }
// console.log(sameArr(arr1,arr2))
4、数组展开flat的实现理解
// const arr = [1,[2],[[3]],[[[4]]]]
// console.log(arr.flat(Infinity))
// es5的做法递归
/* const myFlat = (arg)=>{
let temp = []
if(arg.length<1) return
for(let i=0;i<arg.length;i++){
if(Array.isArray(arg[i])){
temp = temp.concat(myFlat(arg[i]))
}else{
temp.push(arg[i])
}
}
return temp
}
// es6的做法呢是使用some
const myFlat = (arg)=>{
while(arg.some(item=>Array.isArray(item))){
arg = myFlat(arg).concat(...item)
}
return arg
}
console.log(myFlat(arr)) */
5、Promise的理解,根据规范写的一个
/* class MyPromise{
constructor(executor){
this.status = 'pending'
this._value = undefined
this.fulfilledCallbacks = []
this.rejectedCallbacks = []
let resolve = val =>{
const next = ()=>{
if(this.status !=='pending') return
this.status = 'fulfilled'
this._value = val
while(this.fulfilledCallbacks.length){
const callback = this.fulfilledCallbacks.shift()
callback(val)
}
}
setTimeout(next)
}
let reject = val=>{
const next = ()=>{
if(this.status!=='pending') return
this.status = 'rejected'
this._value = val
while(this.rejectedCallbacks.length){
const callback = this.rejectedCallbacks.shift()
callback(val)
}
}
setTimeout(next)
}
try{
executor(resolve,reject)
}catch(err){
reject(err)
}
}
then(onFulfilled,onRejected){
typeof onFulfilled !=='function' ? onFulfilled =val=>val: null
typeof onRejected !=='function' ? onRejected =err=>err: null
return new MyPromise((resolve,reject)=>{ // 返回一个Promise
let fulfilledFn = val =>{
let x = onFulfilled(val)
try{
x instanceof MyPromise ? x.then(resolve,reject) : resolve(x) // 判断返回的一个promise还是一个普通值
}catch(err){
reject(err)
}
}
let rejectedFn = val =>{
let x = onRejected(val)
try{
x instanceof MyPromise ? x.then(resolve,reject): resolve(x)
}catch(err){
reject(err)
}
}
if(this.status === 'pending'){
this.fulfilledCallbacks.push(fulfilledFn)
this.rejectedCallbacks.push(rejectedFn)
}else if(this.status === 'fulfilled'){
fulfilledFn(this._value)
}else {
rejectedFn(this._value)
}
})
}
catch(reject){
return this.then(undefined,reject)
}
resolve(value){
if(value instanceof MyPromise ){
return value
}else{
return new MyPromise(resolve=>resolve(value))
}
}
reject(value){
if(value instanceof MyPromise ){
return value
}else{
return new MyPromise(reject=>reject(value))
}
}
finally(callback){
return this.then(
value=>Promise.resolve(callback()).then(()=>value),
error=>Promise.resolve(callback()).then(()=>{throw error})
)
}
}
*/
// all的规则如下,所有传入的promise都需要执行,如果有reject的只返回 reject的结果,否者返回resolve的结果
const myALlPromise = promiseArr =>{
let index = 0
let result = []
return new MyPromise((resolve,reject)=>{
promiseArr.forEach((element,i) => {
MyPromise.resolve(element).then(
val=>{
index++
result[i] = val
if(index===promiseArr.length){
resolve(result)
}
},
err =>{
reject(err)
}
)
})
})
}
const myRacePromise = promiseArr =>{
return new MyPromise((resolve,reject)=>{
promiseArr.forEach(item=>{
MyPromise.resolve(item).then(
value=>{
resolve(value)
},
error=>{
reject(error)
}
)
})
})
}
*/
// myALlPromise([p3,p2,p1]).then(item=>{
// console.log(item)
// }).catch(err=>{
// console.log(err)
// })
6、new的理解
const Person = function(name,age){
this.name = name
this.age = age
return this
}
const _new = (fn,...arg)=>{
const obj = new Object()
obj.__proto__ = fn.prototype
const result = fn.apply(obj,arg)
if(typeof result ==='object' || typeof result ==='function'){
return result
}else{
return obj
}
}
const newObj = _new(Person,'angular',18)
console.log(newObj)