美文网首页
前端刷题 —— 牛客网前端题库60道详解(四)

前端刷题 —— 牛客网前端题库60道详解(四)

作者: 顽皮的雪狐七七 | 来源:发表于2021-04-14 18:11 被阅读0次

目录

  • 引言

    1. 正确的函数定义 (简单)
    2. 正确的使用 parseInt (入门)
    3. 完全等同 (入门)
    4. 计时器 (中等)
    5. 流程控制 (中等)
    6. 函数传参 (入门)
    7. 函数的上下文 (入门)
    8. 返回函数 (简单)
    9. 使用闭包 (中等)
    10. 二次封装函数 (入门)

引言

牛客网这个前端笔试题库,可以说这60道是最基础的了,也是考察的东西比较杂,有时间4天差不多就可以刷完,巩固基础还是有些用的。做完题回顾一上午就可以过完一遍。现在我结合我的答案和参考的其他人的答案,在这里做一个总结,也是自己知识的整理结果。

31. 正确的函数定义

题目描述
请修复给定的 js 代码中,函数定义存在的问题
输入:true
输出:a

function functions(flag) {
    if (flag) {
      function getValue() { return 'a'; }
    } else {
      function getValue() { return 'b'; }
    }
    return getValue();
}
// 方法一:使用函数表达式
function functions(flag) {
    if (flag) {
      var getValue = ()  => { return 'a'; }
    } else {
      var getValue = () => { return 'b'; }
    }
 
    return getValue();
}

// 上面的等同于下面的,变量提升
function functions(flag) {
    var getValue
    if (flag) {
      getValue = () => { return 'a'; }
    } else {
      getValue = () => { return 'b'; }
    }

    return getValue();
}

相关知识点:

  • 函数的定义方式

函数声明式:函数声明在函数没有执行之前就已经在作用域中会提升,同名的声明会进行覆盖,以下面的为准,那么程序执行的时候一直输出的就是b。

函数表达式:使用函数表达式,还是会进行变量的提升,只不过这次提升的是变量getValue,在执行的时候,才会根据if语句的流程控制执行不同的函数。

31. 正确的使用 parseInt

题目描述
修改 js 代码中 parseInt 的调用方式,使之通过全部测试用例
输入:'12' 输出:12
输入: '12px' 输出:12
输入: '0x12' 输出:0

// 方法,确定是10进制
function parse2Int(num) {
    return parseInt(num,10);
}

相关知识点:

  • parseInt

parseInt经常用于强制类型转换中显式转换成数字,接收两个参数,返回数值或者NaN

parseInt(string, radix)
第一个参数是字符串,必须传的。
第二个参数是数字的基数,2-36,如果不传或者传0都是以10位基数来计算,如果小于2(不等于0)或者大于36一律返回NaN,如果'0x'开头为16进制,'0'开头不包括0是8进制。

parseInt强制类型转化的时候,如果第一位不是数字就会返回NaN,如果第一位是数字,那么会把后面是数字的返回,不是数字的过滤掉。如果是小数的话,会向下取整成整数。

33. 完全等同

题目描述
判断 val1 和 val2 是否完全等同

function identity(val1, val2) {
     return val1 === val2
}

相关知识点:

  • 等同

== 和 === 的区别,简单来说在于,== 只判断值相同,遇到问题,=== 还要判断类型是否相同。
这里其实我觉得还需要考虑NaN的问题,NaN !== NaN

31. 正确的函数定义

题目描述
实现一个打点计时器,要求

  1. 从 start 到 end(包含 start 和 end),每隔 100 毫秒 console.log 一个数字,每次数字增幅为 1
  2. 返回的对象中需要包含一个 cancel 方法,用于停止定时操作
  3. 第一个数需要立即输出
function count(start, end) {
    // 第一个立即输出
    console.log(start++)
    let time = setInterval(function () {
        if(start >= end) clearInterval(time)
        console.log(start++)
    },100)
    return {
        // 返回的方法是一个函数
        cancel: function () {
            clearInterval(time)
        }
    }
}

相关知识点:

  • setInterval

计时器,如果第一个要立即输出,那么需要手动写一次。
定义的时候接收两个参数,第一个是每次执行的函数,第二个是执行时间间隔。
返回值接收计时器名称,可以用于清空计时器用。

  • 闭包

31. 流程控制

题目描述
实现 fizzBuzz 函数,参数 num 与返回值的关系如下:
1、如果 num 能同时被 3 和 5 整除,返回字符串 fizzbuzz
2、如果 num 能被 3 整除,返回字符串 fizz
3、如果 num 能被 5 整除,返回字符串 buzz
4、如果参数为空或者不是 Number 类型,返回 false
5、其余情况,返回参数 num
输入: 15 ; 输出: fizzbuzz

function fizzBuzz(num) {
    // 如果num为空或者不传,isNaN都为true
    if(isNaN(num)) return false
    if(num % 3 === 0 && num % 5 === 0) {
        return 'fizzbuzz'
    } else if (num % 3 === 0) {
        return 'fizz'
    } else if (num % 5 === 0) {
        return 'buzz'
    } else {
        return num
    }
}

相关知识点:

  • 流程控制:if-else
  • isNaN

isNaN(),遇到不是Number类型的判断都用这个函数,如果参数不是数字就返回true,其他的判断我觉得都不是这个题要考的。ES6之后新增了方法Number.isNaN() 判断是否是NaN

  • 取余 %

36. 函数传参

题目描述
将数组 arr 中的元素作为调用函数 fn 的参数
输入:
function (greeting, name, punctuation) {return greeting + ', ' + name + (punctuation || '!');}, ['Hello', 'Ellie', '!']
输出:
Hello, Ellie!

// 方法一:量身定做,传的是数组
function argsAsArray(fn, arr) {
    return fn.apply(this,arr)
}

// 方法二:如果用call就需要使用扩展符打散
function argsAsArray(fn, arr) {
    return fn.call(this,...arr)
}

// 方法三:如果bind处理
function argsAsArray(fn, arr) {
    return fn.bind(this,...arr)()
}

相关知识点:

  • apply/call/bind (详情见一的第一题)
  • fn传参问题

37. 函数的上下文

题目描述
将函数 fn 的执行上下文改为 obj 对象
输入:
function () {return this.greeting + ', ' + this.name + '!!!';}, {greeting: 'Hello', name: 'Rebecca'}
输出:Hello, Rebecca!!!

// 方法一:apply
function speak(fn, obj) {
    return fn.apply(obj)
}

// 方法一:call
function speak(fn, obj) {
    return fn.call(obj)
}

// 方法一:bind
function speak(fn, obj) {
    return fn.bind(obj)()
}

相关知识点:

  • this指向

apply/call/bind 都可以修改执行上下文,如果直接调用fn,this指的是window,如果用 apply/call/bind 可以将this改成对象obj

38. 返回函数

题目描述
实现函数 functionFunction,调用之后满足如下条件:
1、返回值为一个函数 f
2、调用返回的函数 f,返回值为按照调用顺序的参数拼接,拼接字符为英文逗号加一个空格,即 ', '
3、所有函数的参数数量为 1,且均为 String 类型
输入:
functionFunction('Hello')('world')
输出: Hello, world

function functionFunction(str) {
    return function f(...arg) {
        // 记得逗号之后要加一个空格,才能过oj
        return str + ', '+arg
    }
}

相关知识点:

  • 闭包 + 柯里化

闭包的作用是一个函数可以访问另一个函数作用域的变量。

39. 使用闭包

题目描述
实现函数 makeClosures,调用之后满足如下条件:
1、返回一个函数数组 result,长度与 arr 相同
2、运行 result 中第 i 个函数,即 result[i](),结果与 fn(arr[i]) 相同
输入:

[1, 2, 3], function (x) { 
  return x * x; 
}

输出:4

// 闭包
function makeClosures(arr, fn) {
    let result = []
    for(let i = 0; i < arr.length; i++) {
        result.push(function(){
          return fn(arr[i])  
        })
    }
    return result
}

相关知识点:

  • 闭包

上面的题,如果不用闭包,那么for循环的嘶吼,最后调用函数的时候,i都是arr.length,如果使用闭包,可以是当时循环的i值。

40. 二次封装函数

题目描述
已知函数 fn 执行需要 3 个参数。请实现函数 partial,调用之后满足如下条件:
1、返回一个函数 result,该函数接受一个参数
2、执行 result(str3) ,返回的结果与 fn(str1, str2, str3) 一致
输入:
var sayIt = function(greeting, name, punctuation) { return greeting + ', ' + name + (punctuation || '!'); }; partial(sayIt, 'Hello', 'Ellie')('!!!');

输出:Hello, Ellie!!!

// 方法一:直接调用,因为没有涉及到this,这里直接用arguments来获取,因为arguments是类数组
function partial(fn, str1, str2) {
    return function result() {
        return fn(str1,str2,arguments[0])
    }
}

// 方法二:用扩展运算符拿到参数传入,更加的通用
function partial(fn, str1, str2) {
    return function result(...arg) {
        return fn(str1,str2,arg)
    }
}

// 方法二:ES6箭头函数,this指的是undefined
const partial = (fn, str1, str2) => str3 => fn(str1, str2, str3)

相关知识点:

  • 闭包
  • 获取函数参数arguments

arguments 类数组,
获取长度arguments.length
获取元素用数组下标arguments[0]
获取当前执行的函数 arguments.callee (ES5严格模式下禁用)

后面的东西可能会上一些小难度~~~

相关文章

网友评论

      本文标题:前端刷题 —— 牛客网前端题库60道详解(四)

      本文链接:https://www.haomeiwen.com/subject/ykjllltx.html