小芋头君的前端笔试题

笔试题目来自芋头君的知乎live,他在live中要求题目不要公开,但是有几个人这么注重知识版权并信守诺言呢,何况我还是拿来无偿分享和造福前端开发者。

1,尽可能全面正确的解析一个任意url的所有参数为Object。

var url = 'http://www.domain.com/?user=anonymous&id=123&id=456&city=%E5%8C%97%E4%BA%AC&d&enabled';
parseParam(url);
/**
结果:
{
   user: 'anonymous',
   id: [123, 456], // 重复出现的 key 要组装成数组,能被转成数字的就转成数字类型
   city: '北京', // 中文
   enabled: true, // 未指定值的 key 约定值为 true
}
*/

2.实现一个最简单的模板引擎

render('我是{{name}},年龄{{age}},性别{{sex}}',{ name:'姓名', age:18 })
// 结果: 我是姓名,年龄18,性别undefined。
var render = function(tpl,data){
return tpl.replace(/\{\{(.+?)\}\}/g,function(m,m1){
return data[m1]
})
}

3.请用js计算出我到底有多少钱(输出Number类型数字,代码尽量简洁,考虑通用情况)

var string = "我的账户余额:2,235,467.20"; console.log(?);

答案:

new Number(string.replace(/[^0-9.]/g,''))

4.双向绑定的简单实现

// 有一个全局变量 a,有一个全局函数 b,实现一个方法bindData,执行后,a的任何赋值都会触发b的执行。
var a = 1;
function b(){
console.log('a的值发生改变');
}
bindData();
a = 2; // 此时输出 a的值发生改变

答案:

function bindData(target, event){
for(var key in target) {
if(target.hasOwnProperty(key)) {
(function(){
var v = target[key];
Object.defineProperty(target, key, {
get: function() {
return v;
},
set: function(_value) {
v = _value;
event.call(this)
}
})
})()
}
}
}

4,实现一个js class实现数字变化动画

// 实现一个 js 的 class ,名字叫做:AnimateToNum,功能是从某个数字递增或者递减到另外一个数字,并且不管数字如何变化,都可以在指定的时间内完成。
var AnimateToNum = require("animate-num");

var numAnim = new AnimateToNum({
  animTime:2000, //每次数字变动持续的时间(ms),
  initNum:500, //初始化的数字
  onChange:function(num){
    console.log(num);
  }
});
 
numAnim.toNum(100); // 从500变化到100,用2000ms的时间,在onChange回调中会一直从500倒数到100

5,现提供几个读取文件的方法,不借助全局变量实现一个函数,函数可以执行一次后返回一个目录下所有文件中是 .js 后缀的文件列表

var readdirSync = function(dir_path){ return [filename] } // 读取一个文件夹下的所有文件夹和文件的路径列表(Array)
var isDirectory = function(path) { return true/false; } // 判断一个路径是否是文件夹
var existsSync = function(path){ return true/false;} // 判断一个文件/文件夹是否存在
 
var getJSFiles = function(path) {
 
}
getJSFiles('/code/'); // return 一个文件列表的数组

答案:

var getJSFiles = function(path) {
var result = [];
if(existsSync(path)) {
if(isDirectory(path)) {
 var files = readdirSync(path);
 files.forEach((file) => {
 result = result.concat(getJSFiles(file));
 });
 } else if(/\.js$/.test(path)) {
 result.push(path);
 }
}
 return result;
}

6,请封装一个 CustomFetch 方法,利用原生的 fetch api,但是实现以下几个需求: 所有请求默认带上一个 token,值是 xxx 请求返回的时候,内部解析内容,并且判断 success 字段是否是 true,如果不是,在 catch 中可以拿到一个Error,message 和 code 是接口返回的对应的内容

CustomFetch("http://api.com/api").then((data)=>{
    console.log(data); // 如果后台返回 true
}).catch((e)=>{
    console.log(e.message); // 输出 “查询错误”
});
 
// 接口的返回模式
{
    success: false,
    code: 'QUERY_ERROR',
    data: {},
    message: '查询错误'
}

7,将数字转换成中文大写的表示,处理到万级别,例如 12345 -> 一万二千三百四十五

function toLowerNum(){
 
}
console.log(toLowerNum(12345)); // 输出 一万二千三百四十五
console.log(toLowerNum(10001)); // 输出 一万零一
console.log(toLowerNum(10011)); // 输出 一万零十一
console.log(toLowerNum(10000)); // 输出 一万

答案:

function toLowerNum(num){
var number = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'] // 定义中文数字
var unit = ['', '十', '百', '千', '万'] // 定义中文基
var resultStr = []
var len = 0 // 数字长
var lastNumNotZero = false
while(num){
let n = num % 10
let u = len >= unit.length ? len % 5 + 1 : len % 5

// console.log(n, u, len)
// 添加基
// if(n || (len >= unit.length && lastNumNotZero))
if(
n // 当前位存在
|| // 或者
( u == unit.length - 1 && // u 和 长度均为 最后一位unit
len == unit.length - 1
)
)
resultStr.unshift(unit[u])

// 处理数
if(
n || lastNumNotZero // 当前位和前一位不都为零则处理
&& 
u !== unit.length - 1 // 且当前位不为最后一位基
) 
resultStr.unshift(number[n])
lastNumNotZero = !!n
len++
num = Math.floor(num / 10)
}
return resultStr.join('')
}

9,实现一个函数,可以判断 a 字符串是否被包含在 b 字符串中,不能用原生api,自己实现一个字符串查找

答案:

var b='abcabcdef'
var a='cde'
var j = 0;
var m=0;
var result = false;
for(var i=0;i<a.length;i++){
    while(j<b.length&&a[i] != b[j]){
         j++;
    }
    j++;
    if(a[i]!=b[j]) m++
    else m=0
}
if(m==a.length) result = true

10,下面五段代码分别输出什么?并且什么时候输出什么?

for(var i = 0; i < 5; i++) {
    console.log(i);
}
for(var i = 0; i < 5; i++) {
    setTimeout(function() {
        console.log(i);
    }, 1000 * i);
}
for(var i = 0; i < 5; i++) {
    (function(i) {
        setTimeout(function() {
            console.log(i);
        }, i * 1000);
    })(i);
}
for(var i = 0; i < 5; i++) {
    (function() {
        setTimeout(function() {
            console.log(i);
        }, i * 1000);
    })(i);
}
for(var i = 0; i < 5; i++) {
    setTimeout((function(i) {
        console.log(i);
    })(i), i * 1000);
}

参考链接

http://blog.csdn.net/buaa_shang/article/details/9907183

http://www.cnblogs.com/vajoy/p/5341664.html

我要分享

曾小乱

作者: 曾小乱

喜欢写点有意思的东西

《小芋头君的前端笔试题》有2个想法

  1. %E4%B8%8D%E7%9F%A5%E5%BB%89%E8%80%BB%E7%9A%84%E6%AF%94%E7%A0%B8%E7%A2%8E%E7%8E%A9%E6%84%8F,%E4%B8%8D%E5%B0%8A%E9%87%8D%E7%89%88%E6%9D%83%E5%82%BB%E7%8B%97%E7%AF%AE%E5%AD%90%E8%BF%98%E8%BF%99%E4%B9%88%E7%90%86%E7%9B%B4%E6%B0%94%E5%A3%AE?%E6%AF%94%E7%8E%A9%E6%84%8F%E7%A0%B8%E7%A2%8E,%E7%A5%9D%E4%BD%A0%E5%85%A8%E5%AE%B6%E7%88%86%E7%82%B8

    1. 您是大搜车的芋头君么?哈哈,我只能知道你的邮箱:yutoucaonima@gmail.com,你的留言我看不懂。

评论已关闭。