SOURCE

console 命令行工具 X clear

                    
>
console
/**
 * 第一场
 */

//版本号排序
const version = ['1.1', '2.1.2', '3.3', '0.1.4.6', '5.5', '1.1.3', '2.1'];
const handleSort = (item1, item2) => {
    const numList1 = item1.split('.');
    const numList2 = item2.split('.');
    const len1 = numList1.length;
    const len2 = numList2.length;
    const len = Math.max(len1, len2);

    for (let i = 0; i < len; i++) {
        const num1 = numList1[i] || 0;
        const num2 = numList2[i] || 0;
        if (num1 !== num2) {
            return num1 - num2;
        }
    }
}
const versionSort = (arr) => {
    return arr.sort(handleSort);
};

//看代码题
//useState经典问题 在useEffect中设置定时器 
//让计数板++,但是由于是获取的state的闭包值所以不会更新
//解决办法是可以在setState((prev) => prev + 1)

//看代码题
//函数组件的无效嵌套 

//设计题
//设计一个外部不需要loading状态的非受控组件
//思路是在<Loading />组件内部维护自己的loading值 并且劫持它的handleClick事件


/**
 * 第二场
 */

//promise的串行和并行
//设计一个函数 接受一个多维数组
//数组中的每一项的第一项是promise任务,其次是其promise的回掉
//需要promise并行 但其回掉串行
const pr = (key, delay = 1000) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log(`enter${key}`, delay);
            resolve(key);
        }, delay)
    })
};
const queue = [
    [
        2000,
        () => {
            console.log('1 is finish!');
        }
    ],
    [
        1000,
        () => {
            console.log('2 is finish!');
        }
    ],
    [
        3000,
        () => {
            console.log('3 is finish!');
        }
    ],

];
// const fn = (promiseArr) => {
//     return promiseArr.reduce((acc, item, index) => {
//         return acc.then(() => pr(index + 1, item[0]));
//     }, Promise.resolve())
// }
// fn(queue);

const fn = (promiseArr) => {
    const len = promiseArr.length;
    const queue = [];

    const run = () => {
        for (let i = 0; i < len; i++) {
            const { state, fn } = queue[i];
            if (!queue[i]) {
                return;
            } else {
                if (state) {
                    fn();
                    queue[i].state = false;
                }
            }

        }
    }

    for (let i = 0; i < len; i++) {
        pr(i + 1, promiseArr[i][0]).then(() => {
            queue[i] = {
                state: true,
                fn: promiseArr[i][1],
            }
            run();
        });
    }
};
// fn(queue);

//Promise.all的设计
const myPromiseAll = (promiseArr) => {
    const result = [];
    const len = promiseArr.length;
    let total = 0;

    return new Promise((resolve, rejcet) => {
        for (let i = 0; i < len; i++) {
            promiseArr[i].then((res) => {
                result[i] = res;
                total += 1;

                if (total === len) {
                    resolve(result);
                }
            }).catch((e) => {
                reject(e);
            })
        }
    });
};
// myPromiseAll([Promise.resolve(1),
// Promise.resolve(3), Promise.resolve(2)]).then((res) => {
//     console.log('res-', res);
// })

// 二面
//arguments对象
const change = (obj) => {
    obj[0] = 20;

    return obj;
};

const add = function (a, b, c = 5) {
    var a = 10;
    var b = 5;
    change(arguments);
    console.log('enter---', a, b, c);
    return a + b + c;
};
// console.log(add(8, 2, 3));

//promise返回值问题
Promise.resolve('foo').then(Promise.resolve('bar')).then((res) => {
    // console.log('res--', res);
}).catch((e) => {
    console.log('error---', e);
})

//字符串反转
const str = 'abc 1df 21df kkl'; // cba fd1 fd12 lkk

const revser = (target) => {
    const len = target.length;
    let result = '';

    for (let i = len - 1; i >= 0; i--) {
        result += target[i];
    }

    return result;
};

const reverseStr = (s) => {
    const len = s.length;
    let temp = '';
    let result = '';

    for (let i = 0; i < len; i++) {
        if (s[i] !== ' ') {
            temp += s[i];
        } else {
            result += revser(temp) + ' ';
            temp = '';
        }
    }
    if (temp) {
        result += revser(temp);
    }

    return result;
};
// console.log(reverseStr(str));


/**
 * 第三场
 */
//实现new关键字
const myNew = function (constructorFn, ...args) {
    if (typeof constructorFn !== 'function') {
        throw TypeError(`${constructorFn} must be a function`);
    }
    myNew.target = constructorFn;//new.target 检验是否通过new关键字调用

    const obj = {};

    Object.setPrototypeOf(obj,
        constructorFn.prototype instanceof Object ?
            constructorFn.prototype : Object.prototype);
    const fnRes = constructorFn.apply(obj, args);

    return fnRes instanceof Object ? fnRes : obj;

}


//this 打印顺序
var name = 'window';

const thisObj = {
    name: 'obj',
    fn1: function () {
        console.log(this.name);
    },
    fn2: () => {
        console.log(this.name);
    },
    fn3: function () {
        return function () {
            console.log(this.name);
        }
    },
    fn4: function () {
        const name = 'fn4';
        return () => {
            console.log(this.name);
        }
    },
    fn5: () => {
        return () => {
            console.log(this.name);
        }
    }
};
const run = () => {
    for (let i = 0; i < 5; i++) {
        const item = thisObj[`fn${i + 1}`]();
        if (typeof item === 'function') {
            item();
        }
    }
};
// run();
// const testObj = {
//     name: 'test'
// }
// thisObj.fn1.call(testObj);
// thisObj.fn2.call(testObj);


//event loop


//实现curry函数 满足 fn(1,2,3)(1)(4,5,6)
// const curryAdd = (...args1) => {
//     const queue = [...args1];

//     const sum = () => {
//         return queue.reduce((acc, item) => acc + item);
//     }

//     const add = (...args2) => {
//         queue.push(...args2);
//         return add;
//     }

//     add.toString = sum;

//     return add;
// };
// console.log(curryAdd(1, 2, 3)(1));

// const curry = (fn) => {
//     let argLen = 0;

//     function fun(...args) {
//         if (args.length > argLen) {
//             argLen = args.length;
//             return fun.bind(null, ...args);
//         } else {
//             return fn.apply(null, args);
//         }
//     }

//     return fun;
// };
// const sum = (...args) => {
//     return args.reduce((acc, item) => acc + item, 0);
// };
// const add2 = curry(sum);
// console.log(add2(1, 2, 3)(4, 5, 6)());

const sum = (arr) => {
    return arr.reduce((acc, item) => acc + item, 0);
};
const add3 = (...args1) => {
    const total = sum(args1);
    return (...args2) => {
        if (args2.length) {
            return add3(total, ...args2);
        }
        return total;
    }
};
// console.log(add3(1, 2, 3)(3, 4)());

/**
 * 第四场
 */

//event loop


//this 箭头函数 


//最长回文字串
// const checkPalindrome = (str) => {
//     const len = str.length;
//     let i = 0;
//     let j = len - 1;

//     while (i <= j) {
//         if (str[i] !== str[j]) {
//             return false;
//         }
//         i++;
//         j--;
//     }
//     return true;
// };

// const findMaxSubPalindrome = (str) => {
//     const len = str.length;
//     let max = '';

//     if (len <= 1) {
//         return str;
//     }
//     for (let i = 0; i < len; i++) {
//         for (let j = len - 1; j > i; j--) {
//             if (str[j] === str[i]) {
//                 const sub = str.slice(i, j + 1);
//                 if (checkPalindrome(sub) && sub.length > max.length) {
//                     max = sub;
//                 }
//             }
//         }
//     }

//     return max || str[0];
// };
// console.log(findMaxSubPalindrome('bananas'));

const longestPalindrome = (str) => {
    //dp[i][j] = dp[i -1][j + 1] && s[i] === s[j];
    const len = str.length;
    if (len <= 1) {
        return str;
    }
    const arr = [];
    let begin = 0;
    let max = 0;



    for (let i = 0; i < len; i++) {
        arr[i] = [];
        let j = 0;

        while (j <= i) {
            if (str[i] === str[j] && (i - j <= 1 || arr[i - 1][j + 1])) {
                arr[i][j] = true;
                if (i - j > max) {
                    max = i - j;
                    begin = j;
                }
            }
            j++;
        }
    }

    return str.substr(begin, max + 1);
};
// console.log(longestPalindrome('abdsddsde'));


//网络缓存



/**
 * 第五场
 */

//css动画

//event loop
const loopFn = () => {
    Promise.resolve().then(() => {
        console.log('1');
        setTimeout(() => {
            console.log('2')
            Promise.resolve().then(() => {
                console.log('3')
            })
        }, 2000)
    });
    setTimeout(() => {
        console.log('4');
        Promise.resolve().then(() => {
            console.log('5');
            setTimeout(() => {
                console.log('6')
            }, 3000);
        })
    }, 1000)

    console.log('7');
};
// loopFn()

//模拟实现红路灯


//实现apply,call,bind
//call
Function.prototype.myApply = function (thisObj, argsArr) {
    try {
        if (typeof this !== 'function') {
            throw TypeError();
        }
        const O = thisObj || window;
        const sym = Symbol('fn');
        O[sym] = this;
        const result = O[sym](...argsArr);
        return result;
    } catch (e) {
        return e;
    }
}
//bind
Function.prototype.myBind = function (thisFn, ...args1) {
    try {
        if (typeof this !== 'function') {
            throw TypeError();
        }

        const O = thisFn || window;

        const that = this;

        const fn = function (...args2) {
            const ctx = this instanceof fn ? this : O;
            return that.apply(ctx, [...args1, ...args2]);
        }

        // fn.prototype = Object.create(that);
        fn.prototype = {
            constructor: fn,
            __proto__: that.prototype
        }

        return fn;
    } catch (e) {
        return e;
    }
}
// console.log(Array.prototype.reduce.bind([1, 2, 3, 4], (acc, item, index) => acc + item)(),
//     Array.prototype.reduce.myBind([1, 2, 3, 4], (acc, item, index) => acc + item)()
// );



<div class="animate-rotate"></div>
@keyframes spin {
    to {
        transform: rotate(.5turn)
    }
}

@keyframes changeBG {
    50% {
        background-color: #655;
    }
}

.animate-rotate {
    width: 200px;
    height: 200px;
    border-radius: 50%;
    background: yellowgreen;
    background-image: linear-gradient(to right, transparent 50%, #655 0);
}

.animate-rotate::before {
    content: '';
    display: block;
    margin-left: 50%;
    height: 100%;
    background-color: inherit;
    border-radius: 0 100% 100% 0 /50%;
    transform-origin: left;
    transform: rotate(.01turn);
    /* animation: spin 1s linear 2, changeBG 2s step-end 2; */
}