loading...

0

原生js面试题面向高级

javascript读完大概需要21分钟

  • 发布时间:2018-10-22 14:10 星期一
  • 刘伟波
  • 407
  • 更新于2018-11-21 16:24 星期三

这三题原本是公司为招聘的前端开发工程师定职级准备的题目,分别考察了库里化、中间件、回调函数的应用。独乐乐不如众乐乐,分享给大家,共同提升对原生js的理解~

话不多说,亮题~

大家如果有更好的实现方法欢迎提出探讨~

编写curry.js

实现函数的分步调用

var curry = require('./curry.js');// <- this is the file you make;

function add(a, b) {
    return a + b;
}

var curried = curry(add);
console.log(curried(1)(2));

function add2(a, b, c) {
    return a + b + c;
}

var curried2 = curry(add2);
console.log(curried2(1)(2)(3));

function add3(a, b, c, d) {
    return a + b + c + d;
}

var curried3 = curry(add3);
console.log(curried3(1)(2)(3)(4));

编写middleware.js

实现中间件类,可以使用use添加中间件,go执行

var Middleware = require('./middleware.js');  // <- this is the file you make;

var middleware = new Middleware();

middleware.use(function(next) {
    var self = this;
    setTimeout(function() {
        self.hook1 = true;
        next();
    }, 10);
});

middleware.use(function(next) {
    var self = this;
    setTimeout(function() {
        self.hook2 = true;
        next();
    }, 10);
});

var start = new Date();
middleware.go(function() {
    console.log(this.hook1); 
    // true
    console.log(this.hook2); 
    // true
    console.log(new Date() - start); 
    // around 20
});

编写async.js

实现一个async对象,为此对象封装了方法,可以进行事件的队列、并行、竞速的处理。

var async = require('./async.js');// <- this is the file you make;

var getUser = function(userId) {
    return function(cb) {
        setTimeout(function() {
            cb(null, {userId: userId, name: 'Joe'});
        },  100);
    };
};

var upperCaseName = function(cb, user) {
    cb(null, user.name.toUpperCase());
};

var lowerCaseName = function(cb, name) {
    cb(null, name.toLowerCase())
}

var userThunk = getUser(22);

async.sequence([userThunk, upperCaseName,lowerCaseName])(function(err, data) {
    console.log(data); 
});


var userThunk1 = getUser(1);
var userThunk2 = getUser(2);

async.parallel([userThunk1, userThunk2])(function(err, users) {
    console.log(users); 
    // [ { userId: 1, name: 'Joe' }, { userId: 2, name: 'Joe' } ]
});

var faster = function(cb) {
    setTimeout(cb.bind(null, null, "I'm faster"), 10);
};

async.race([userThunk1, faster])(function(err, winner) {
    console.log(winner); 
    // I'm faster
});

答案分割线


  1. curry
function curry (fn){
    var args = [].slice.call(arguments, 1)
    return function () {
        const newArgs = args.concat(Array.from(arguments))
        if (newArgs.length < fn.length) {
            return curry(fn, ...newArgs)
        } else{
            return fn(...newArgs)
        }
    }
}
module.exports = curry;
  1. MiddleWare
/**
 * 构造函数 
 * 函数为参数,函数内部this共享
 * use,go方法定下中间件队列,同步执行
 * 调用next可以进入下一步,如果没有调用就会停止
 */
class MiddleWare {
    constructor() {
        this.queue = []
    }
    use(fn) {
        this.queue.push(fn)
        return this
    }
    go(fn) {
        this.queue.push(fn)
        this.next()
    }
    next() {
        if( this.queue.length > 0  ){
            var fn = this.queue.shift()
            fn.call(this, this.next.bind(this))
        }
    }
}


 module.exports = MiddleWare
  1. async
/**
 * 实现async对象,对promise进行封装
 * 函数1:队列模式,有先后关系
 *  前一个事件函数中执行cb第一个参数为报错, 第二个参数为结果
 *  最后后一个时间函数接受参数,第一个为cb,第二个参数为前一次的结果    前一个函数调用后面的callback
 * 函数2:并行模式,同时执行
 * 函数3:竞速模式,执行先到达的那个
 */

 const async = {
    sequence(events) {
        var length = events.length;
        var i = 0;
        return function(cb) {
            var middleFn = function(error, data){
                if( !error ) {
                    if( i + 2 >= length ) {
                        events[++i](cb, data)
                    } else {
                        events[++i](middleFn, data)
                    }
                } else {
                    throw new Error({message: error})
                }
            }
            events[0](middleFn)
        }
    },
    parallel(events) {
        return function(cb) {
            events.forEach(fn => {
                fn(cb)
            })
        }
    },
    race(events) {
        return function (cb){
            var isDone = false
            var fnCall = function(err, data) {
                if( isDone ) {
                    return 
                }
                isDone = true
                cb(err, data)
            }
            events.forEach(fn => {
                fn(fnCall)
            })
        }
    }
 }

 module.exports = async

打开一个网页经历了那些过程?

http://web.jobbole.com/94150/

浏览器加载白屏是什么原因?

https://github.com/Mountain-Buzhou/Interview-Book/blob/master/docs/Collection/WhiteScreen.md

千万访问量的项目,前端需要注意些什么?

https://github.com/Mountain-Buzhou/Interview-Book/blob/master/docs/Collection/DozensOfVisits.md

实现一个promise

https://github.com/Liyuk/code-repertory/blob/master/promise/promise.js

HTTP 2.0与HTTP 1.1区别

https://www.cnblogs.com/frankyou/p/6145485.html

每个 JavaScript 工程师都应懂的33个概念

https://github.com/stephentian/33-js-concepts

一年半经验,百度、有赞、阿里面试总结

https://juejin.im/post/5befeb5051882511a8527dbe

前端技术清单

https://github.com/alienzhou/frontend-tech-list

美团技术团队

https://tech.meituan.com/

更多

https://github.com/Mountain-Buzhou/Interview-Book

https://github.com/brickspert/blog/issues/16
<br>
作者:刘伟波

链接:http://www.liuweibo.cn/p/226

来源:刘伟波博客

本文原创版权属于刘伟波 ,转载请注明出处,谢谢合作

你可能感兴趣的文章

    发表评论

    评论支持markdown,评论内容不能超过500字符,如果内容过多或者要及时回复,建议去 segmentfault平台, 也可以来我的直播间来提问。
    关于技术问题或者有啥不懂的都可以留言, 我会定期回复答疑, 也可以来 我的直播间 提问, 推荐最新仓库 前端知识体系, 感謝支持!