这些基础题你都会了吗——前端灵魂60问(上)

282 阅读7分钟

前言

笔者准备21届春招过程中,发现了牛客网的《前端大挑战》60道基础题(链接:www.nowcoder.com/ta/front-en…),题目虽然简单,作为前端扫盲题还是有刷一遍的必要的。题解为笔者手打,全部通过了牛客网测试。下面是基础题60道的前三十道,我们一起来看看吧!
后三十道链接:juejin.cn/post/694067…

FED1 修改 this 指向

题目描述: 封装函数 f,使 f 的 this 指向指定的对象

function bindThis(f, oTarget) {
   return f.bind(oTarget)
}

FED2 获取 url 中的参数

题目描述: 获取 url 中的参数

  1. 指定参数名称,返回该参数的值 或者 空字符串
  2. 不指定参数名称,返回全部的参数对象 或者 {}
  3. 如果存在多个同名参数,则返回数组 输入: www.nowcoder.com?key=1&key=2&key=3&test=4#hehekey

输出: [1, 2, 3]

function getUrlParam(sUrl, sKey) {
    let left = sUrl.indexOf('?') + 1
    let right = sUrl.lastIndexOf('#')
    let parasString = sUrl.slice(left, right)
    let paras = parasString.split('&')
    let parasJson = {}
    paras.forEach((value, index, arr) => {
        let a = value.split('=')
        parasJson[a[0]] !== undefined
            ? parasJson[a[0]] = [].concat(parasJson[a[0]], a[1])
            : parasJson[a[0]] = a[1]
    })
    let result = sKey !== undefined ? (parasJson[sKey] || '') : parasJson
    return result
}

FED3 dom 节点查找

题目描述: 查找两个节点的最近的一个共同父节点,可以包括节点自身

oNode1 和 oNode2 在同一文档中,且不会为相同的节点

function commonParentNode(oNode1, oNode2) {
    if (oNode1 === oNode2) return oNode1
    let s = new Set()
    while (!s.has(oNode1) && !s.has(oNode2)) {
        s.add(oNode1)
        s.add(oNode2)
        if (oNode1.parentNode) oNode1 = oNode1.parentNode
        if (oNode2.parentNode) oNode2 = oNode2.parentNode       
    }
    return s.has(oNode1) ? oNode1 : oNode2
}

FED4 根据包名,在指定空间中创建对象

题目描述: 根据包名,在指定空间中创建对象

输入: namespace({a: {test: 1, b: 2}}, 'a.b.c.d')

输出: {a: {test: 1, b: {c: {d: {}}}}}

function namespace(oNamespace, sPackage) {
    let name = sPackage.split('.')
    let res = oNamespace
    for (let i in name) {
        if (typeof oNamespace.hasOwnProperty(name[i])) {
            if (typeof oNamespace[name[i]] !== 'object') {
                oNamespace[name[i]] = {}
            }
        } else {
            oNamespace[name[i]] ={}
        }
        oNamespace = oNamespace[name[i]]
    }
}

FED5 数组去重

题目描述: 为 Array 对象添加一个去除重复项的方法

输入: [false, true, undefined, null, NaN, 0, 1, {}, {}, 'a', 'a', NaN]

输出: [false, true, undefined, null, NaN, 0, 1, {}, {}, 'a']

Array.prototype.uniq = function () {
    // return [... new Set(this)] es6解法
    let res = []
    let hasNaN = false
    this.forEach(e => {
        if (res.indexOf(e) === -1) {
            if  (e !== e) {
                if (!hasNaN) {
                    res.push(e)
                    hasNaN = true
                }
            } else {
                res.push(e)
            }
        }
    })
    return res
}

FED6 斐波那契数列

题目描述: 用 JavaScript 实现斐波那契数列函数,返回第n个斐波那契数。 f(1) = 1, f(2) = 1 等

function fibonacci(n) {
//判断 f(2)=1 f(2)=1
if(n==2||n==1){
return 1;
}
//f(n)=f(n-1)+f(n-2)
return fibonacci(n-1)+fibonacci(n-2)
}

FED7 时间格式化输出

题目描述: 按所给的时间格式输出指定的时间

格式说明
对于 2014.09.05 13:14:20
yyyy: 年份,2014
yy: 年份,14
MM: 月份,补满两位,09
M: 月份, 9
dd: 日期,补满两位,05
d: 日期, 5
HH: 24制小时,补满两位,13
H: 24制小时,13
hh: 12制小时,补满两位,01
h: 12制小时,1
mm: 分钟,补满两位,14
m: 分钟,14
ss: 秒,补满两位,20
s: 秒,20
w: 星期,为 ['日', '一', '二', '三', '四', '五', '六'] 中的某一个,本 demo 结果为 五

输入: formatDate(new Date(1409894060000), 'yyyy-MM-dd HH:mm:ss 星期w')

输出: 2014-09-05 13:14:20 星期五

function formatDate(oneDate, formatStr) {
    const obj = {
        yyyy: oneDate.getFullYear(),
        yy: ('' + oneDate.getFullYear()).slice(-2),
        MM: ('0' + (oneDate.getMonth() + 1)).slice(-2),
        M: oneDate.getMonth() + 1,
        dd: ('0' + oneDate.getDate()).slice(-2),
        d: oneDate.getDate(),
        HH: ('0' + oneDate.getHours()).slice(-2),
        H: oneDate.getHours(),
        hh: ('0' + oneDate.getHours() % 12).slice(-2),
        h: oneDate.getHours() % 12,
        mm: ('0' + oneDate.getMinutes()).slice(-2),
        m: oneDate.getMinutes(),
        ss: ('0' + oneDate.getSeconds()).slice(-2),
        s: oneDate.getSeconds(),
        w: ['日', '一', '二', '三', '四', '五', '六'][oneDate.getDay()]   
    }
    for (let el in obj) {
        formatStr = formatStr.replace(el, obj[el])
    }
    return formatStr
}

FED8 获取字符串的长度

题目描述: 如果第二个参数 bUnicode255For1 === true,则所有字符长度为 1 否则如果字符 Unicode 编码 > 255 则长度为 2

输入: 'hello world, 牛客', false

输出: 17

function strLength(s, bUnicode255For1) {
    if (bUnicode255For1) {
        return s.length
    } else {
        let len = s.length
        for( var i=0; i<s.length; i++ ){
            if( s.charCodeAt(i) > 255 ){
                len++;
            }
        }
        return len;
    }
}

FED9 邮箱字符串判断

**题目描述:判断输入是否是正确的邮箱格式 **

输入: 邮箱字符串

输出: true表示格式正确

function isAvailableEmail(sEmail) {
    var reg=/^([\w+\.])+@\w+([.]\w+)+$/;

    return reg.test(sEmail);
}

FED10 颜色字符串转换

题目描述:将 rgb 颜色字符串转换为十六进制的形式,如 rgb(255, 255, 255) 转为 #ffffff

  1. rgb 中每个 , 后面的空格数量不固定
  2. 十六进制表达式使用六位小写字母
  3. 如果输入不符合 rgb 格式,返回原始输入

输入: 'rgb(255, 255, 255)'

输出: #ffffff

function rgb2hex(sRGB) {
      return sRGB.replace(/^rgb\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)\)$/,function(num,num1,num2,num3){ 
       //考虑越界问题
       if (num1<0 || num1>255 || num2<0 || num2>255 || num3<0 || num3>255) {
           return num;
       }
       else{
        function rgb(s){
        if (s<16) {
            //位数不够时补0
            return '0'+parseInt(s).toString(16);
        }
        else{
            return parseInt(s).toString(16);
        }
        }
        return '#'+rgb(num1)+rgb(num2)+rgb(num3);
    }
    });
}

FED11 将字符串转换为驼峰格式

题目描述:css 中经常有类似 background-image 这种通过 - 连接的字符,通过 javascript 设置样式的时候需要将这种样式转换成 backgroundImage 驼峰格式,请完成此转换功能

  1. 以 - 为分隔符,将第二个起的非空单词首字母转为大写
  2. -webkit-border-image 转换后的结果为 webkitBorderImage

输入: 'font-size'

输出: fontSize

function cssStyle2DomStyle(sName) {
    let arr = sName.split('')
    if (arr[0] == '-') {
        arr.splice(0, 1)
    }
    for (let i = 0; i < arr.length; i++) {
       if (arr[i] == '-') {
            arr.splice(i, 1)
           arr[i] = arr[i].toUpperCase()
       }
    }
    return arr.join('')
}

FED12 字符串字符统计

题目描述:统计字符串中每个字符的出现频率,返回一个 Object,key 为统计字符,value 为出现频率

  1. 不限制 key 的顺序
  2. 输入的字符串参数不会为空
  3. 忽略空白字符

输入: 'hello world'

输出: {h: 1, e: 1, l: 3, o: 2, w: 1, r: 1, d: 1}

function count(str) {
    let obj = {}
    for (let i = 0; i < str.length; i++) {
        if (obj[i] !== ' ') {
            let key = str[i]
            if(!obj.hasOwnProperty(str[i])){
                obj[str[i]] = 1;
            } else {
                obj[str[i]]++;
              }
        }
    }
    return obj;
}

FED13 加粗文字

题目描述:使用一个标签将“牛客网”三个字加粗显示

<p><strong>牛客网</strong>,程序员必备求职神器</p>

FED14 段落标识

题目描述:请将下面这句话以段落的形式展示在浏览器中——“牛客网是一个专注于程序员的学习和成长的专业平台。”

<p>牛客网是一个专注于程序员的学习和成长的专业平台。</p>

FED15 设置文字颜色

题目描述:请使用嵌入样式将所有p标签设置为红色文字

<p>欢迎来到牛客网</p>
<p>在这里,我们为你提供了IT名企的笔试面试题库</p>
<p>在这里,我们以题会友</p>
<p>QQ群号:272820159</p>
<style>
p {
    color:red;
}
</style>

FED16 查找数组元素位置

题目描述:找出元素 item 在给定数组 arr 中的位置

输入: [ 1, 2, 3, 4 ], 3

输出: 2

function indexOf(arr, item) {
    return arr.indexOf(item)
}

FED17 数组求和

题目描述:计算给定数组 arr 中所有元素的总和
数组中的元素均为 Number 类型

输入: [ 1, 2, 3, 4 ]

输出: 10

function sum(arr) {
    var sum = 0
    for (var i = 0; i < arr.length; i++) {
        sum += arr[i]
    }
    return sum
}

FED18 移除数组中的元素

题目描述:移除数组 arr 中的所有值与 item 相等的元素。不要直接修改数组 arr,结果返回新的数组

输入: [1, 2, 3, 4, 2], 2

输出: [1, 3, 4]

function remove(arr, item) {
    const newArr = []
    arr.forEach((el, index) => {
        if (el !== item) {
            newArr.push(el)
        }
    })
    return newArr
}

FED19 移除数组中的元素

题目描述:移除数组 arr 中的所有值与 item 相等的元素,直接在给定的 arr 数组上进行操作,并将结果返回

输入: [1, 2, 2, 3, 4, 2, 2], 2

输出: [1, 3, 4]

function removeWithoutCopy(arr, item) {
    arr.forEach((el, index) => {
        if (item = el) {
            arr.splice(index, 1)
        }
        index--
    })
    return arr
}

FED20 添加元素

题目描述:在数组 arr 末尾添加元素 item。不要直接修改数组 arr,结果返回新的数组

输入: [1, 2, 3, 4], 10

输出: [1, 2, 3, 4, 10]

function append(arr, item) {
   return arr.concat([item])
}

FED21 删除数组最后一个元素

题目描述:删除数组 arr 最后一个元素。不要直接修改数组 arr,结果返回新的数组

输入: [1, 2, 3, 4]

输出: [1, 2, 3]

function truncate(arr) {
    let newArr = [...arr]
    newArr.pop()
    return newArr
}

FED22 添加元素

题目描述:在数组 arr 开头添加元素 item。不要直接修改数组 arr,结果返回新的数组

输入: [1, 2, 3, 4], 10

输出: [10, 1, 2, 3, 4]

function prepend(arr, item) {
    let newArr = [...arr]
    newArr.unshift(item)
    return newArr
}

FED23 删除数组第一个元素

题目描述:删除数组 arr 第一个元素。不要直接修改数组 arr,结果返回新的数组

输入: [1, 2, 3, 4]

输出: [2, 3, 4]

function curtail(arr) {
    let newArr = [...arr]
    newArr.shift()
    return newArr
}

FED24 数组合并

题目描述:合并数组 arr1 和数组 arr2。不要直接修改数组 arr,结果返回新的数组

输入: [1, 2, 3, 4], ['a', 'b', 'c', 1]

输出: [1, 2, 3, 4, 'a', 'b', 'c', 1]

function concat(arr1, arr2) {
    return arr1.concat(arr2)
}

FED25 添加元素

题目描述:在数组 arr 的 index 处添加元素 item。不要直接修改数组 arr,结果返回新的数组

输入: [1, 2, 3, 4], 'z', 2

输出: [1, 2, 'z', 3, 4]

function insert(arr, item, index) {
    let newArr = [...arr]
    newArr.splice(index, 0, item)
    return newArr
}

FED26 计数

题目描述:统计数组 arr 中值等于 item 的元素出现的次数

输入: [1, 2, 4, 4, 3, 4, 3], 4

输出: 3

function count(arr, item) {
    let count = 0
    arr.forEach((el) => {
        if (el == item) {
            count++
        }
    })
    return count
}

FED27 查找重复元素

题目描述:找出数组 arr 中重复出现过的元素

输入: [1, 2, 4, 4, 3, 3, 1, 5, 3]

输出: [1, 3, 4]

function duplicates(arr) {
    let newArr = [];
    arr.forEach((el, index)=>{
        if(newArr.indexOf(el) == -1 && arr.indexOf(el) !== arr.lastIndexOf(el)){
            newArr.push(el);
        }
    })
    return newArr;
}

FED28 求二次方

题目描述:为数组 arr 中的每个元素求二次方。不要直接修改数组 arr,结果返回新的数组

输入: [1, 2, 3, 4]

输出: [1, 4, 9, 16]

function square(arr) {
    return arr.map(el => Math.pow(el,2))
}

FED29 查找元素位置

题目描述:在数组 arr 中,查找值与 item 相等的元素出现的所有位置

输入: ['a','b','c','d','e','f','a','b','c'] 'a'

输出: [0, 6]

function findAllOccurrences(arr, target) {
    let newArr = []
    arr.forEach((el, index) => {
        if (el === target) {
            newArr.push(index)
        }
    })
    return newArr
}

FED30 避免全局变量

题目描述:给定的 js 代码中存在全局变量,请修复

function globals() { myObject = { name : 'Jory' }; return myObject; }

function globals() {
    var myObject = {
      name : 'Jory'
    };

    return myObject;
}