题目来源牛客网:https://www.nowcoder.com/ta/front-end
1. 封装函数 f,使 f 的 this 指向指定的对象 1 2 3 4 5 function bindThis (f, oTarget ) { return function ( ) { return f.apply(oTarget, arguments ); } }
2. 获取 url 中的参数
指定参数名称,返回该参数的值 或者 空字符串
不指定参数名称,返回全部的参数对象 或者 {}
如果存在多个同名参数,则返回数组
示例:
输入:http://www.nowcoder.com?key=1&key=2&key=3&test=4#hehe 参数名称: key
输出: [1, 2, 3]
思路:
首先将url根据?号、#号分段,得到中间参数的那一段。
使用replace找到所有符合key=value形式的匹配项,进行全局搜索替换需要在正则表达式中包含g标志。
在替换函数中i表示匹配项,k表示第一个捕获组,v表示第二个捕获组。
通过result[k] instanceof Array
来判是不是数组对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 function getUrlParam1 (sUrl, sKey ) { sUrl = sUrl.split('#' )[0 ].split('?' )[1 ]; var result = {}; sUrl.replace(/(\w+)=(\w+)/g , function (i, k, v ) { if (k in result) { if (result[k] instanceof Array ) { result[k].push(v); } else { result[k] = [result[k], v]; } } else { result[k] = v; } }) return sKey == undefined ? result: result[sKey] || '' ; }
3 .查找两个节点的最近的一个共同父节点 查找两个节点的最近的一个共同父节点,可以包括节点自身
思路:
有一个contains方法可以判断某个节点是不是当前节点的子节点。
1 2 3 4 5 6 7 8 function commonParentNode (n1, n2 ) { for (;n1;n1=n1.parentElement) { if (n1.contains(n2)) { return n1 } } }
4.根据包名,在指定空间中创建对象
输入:namespace({a: {test: 1, b: 2}}, ‘a.b.c.d’)
输出:{a: {test: 1, b: {c: {d: {}}}}}
思路:
遍历sPackage,对每一个包名,判断它在oNamespace里面是不是对象,如果不是这创建这个对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 function namespace (oNamespace, sPackage ) { var packages = sPackage.split('.' ), result = oNamespace; for (var i = 0 ; i < packages.length; i++) { var l = packages[i]; if (typeof oNamespace[l] != "object" ) { oNamespace[l] = {} } oNamespace = oNamespace[l] } oNamespace = result return result }
5. 为 Array 对象添加一个去除重复项的方法
输入:[false, true, undefined, null, NaN, 0, 1, {}, {}, ‘a’, ‘a’, NaN]
输出:[false, true, undefined, null, NaN, 0, 1, {}, {}, ‘a’]
对于undefined、null都是可以通过Array.prototype.indexOf来看是否已经包含在res中,唯一需要判断的是NaN,对于arr = [NaN], arr.indexOf(NaN)会返回-1,所以每次indexOf返回-1都需要通过item!=item && (typeof item == “number”)来判断item是NaN。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 Array .prototype.uniq = function ( ) { var res = [], findNaN = true ; this .forEach(function (item ) { if (res.indexOf(item) != -1 ) { return ; } if (item !== item && (typeof item==="number" ) ) { if (findNaN) { res.push(item) findNaN = false ; } return ; } res.push(item) }) return res; }
6. 斐波那契数列
输入:fibonacci(3)
输出:2
输入:fibonacci(4)
输出:3
1 2 3 4 5 6 7 8 9 10 function fibonacci (n ) { var a = 0 , b = 1 ; for (var i = 2 ; i <= n; i++) { var t = a; a = b; b += t; } return b; }
7.时间格式化输出
输入:formatDate(new Date(1409894060000), ‘yy-MM-dd hh:mm:ss 星期w’)
输出:14-09-05 01:14:20 星期五
思路:需要注意的是date的那些getXXXX的方法都是从0开始计数,getDay()从周日开始。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 function formatDate (date, format ) { function addZero (num ) { if (num < 10 ) return "0" + num; return num; } return format.replace(/([a-zA-Z]+)/g , function (item, group ) { if (item === 'yyyy' ) return date.getFullYear(); if (item == 'yy' ) return date.getFullYear()%100 ; if (item == 'MM' ) return addZero(date.getMonth()+1 ); if (item == 'M' ) return date.getMonth()+1 ; if (item == 'dd' ) return addZero(date.getDate()); if (item == 'd' ) return date.getDate(); if (item == 'HH' ) return addZero(date.getHours()); if (item == 'H' ) return date.getHours(); if (item == 'hh' ) return addZero(date.getHours()%12 ); if (item == 'h' ) return date.getHours()%12 ; if (item == 'mm' ) return addZero(date.getMinutes()); if (item == 'm' ) return date.getMinutes(); if (item == 'ss' ) return addZero(date.getSeconds()); if (item == 's' ) return date.getSeconds(); if (item == 'w' ) return ['日' ,'一' ,'二' ,'三' ,'四' ,'五' ,'六' ][date.getDay()]; }) }
8.获取字符串长度 如果第二个参数bUnicode255For1为false,那么unicode编码大于255的字符表示的长度为2,否则所有字符长度为1。
输入:’hello world, 牛客’, false
输出:17
1 2 3 4 5 6 7 8 function strLength (s, bUnicode255For1 ) { if (bUnicode255For1) return s.length; var length = 0 ; for (var i = 0 ; i < s.length; i++) { length += s.charCodeAt(i) > 255 ? 2 : 1 ; } return length }
9. 邮件字符串判断 判断输入是否是正确的邮件格式
输入:shao@gmail.com
输出: true
输入:dsa.shao@gmail.com
输出: true
输入:sh@ao@gmail.com
输出: false
1 2 3 function isAvailableEmail (sEmail ) { return /^\w+(\.\w+)*@\w+(\.\w+)+$/ .test(sEmail) }
10. 颜色字符串转换 描述:
将 rgb 颜色字符串转换为十六进制的形式,如 rgb(255, 255, 255) 转为 #ffffff
rgb 中每个 , 后面的空格数量不固定
十六进制表达式使用六位小写字母
如果输入不符合 rgb 格式,返回原始输入
输入:’rgb(255, 255, 255)’
输出:#ffffff
输入:’rgb(0,32,255)
输出:#0020ff
思路:
主要还是使用正则来匹配替换。toHex函数使用toString(16)来将数字转换为16进制,然后通过前面加0来剪成两位。比如”2”在parseInt后变为2,在toString(16)后变为16进制,通过前面加0变为02,然后slice剪出从倒数第二到最后的子字符串。
1 2 3 4 5 6 7 function rgb2hex (sRGB ) { function toHex (num ) { return ("0" + parseInt (num).toString(16 )).slice(-2 ); } return sRGB.replace(/^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/ , function (rgb, r, g, b ) { return '#' + toHex(r) + toHex(g) + toHex(b); }) }
11.将字符串转换为驼峰格式 css 中经常有类似 background-image 这种通过 - 连接的字符,通过 javascript 设置样式的时候需要将这种样式转换成 backgroundImage 驼峰格式,请完成此转换功能
以 - 为分隔符,将第二个起的非空单词首字母转为大写
-webkit-border-image 转换后的结果为 webkitBorderImage
样例
输入:’font-size’
输出:’fontSize’
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 function cssStyle2DomStyle (sName ) { function toUpper (s ) { return s[0 ].toUpperCase()+s.slice(1 ) } var names = sName.split('-' ), result = "" , first = true ; for (var i = 0 ; i < names.length; i++) { if (names[i].length == 0 ) continue ; if (first) { result += names[i]; first = false ; } else result += toUpper(names[i]); } return result; }
字符串字符统计 题目描述:
统计字符串中每个字符的出现频率,返回一个 Object,key 为统计字符,value 为出现频率
不限制 key 的顺序
输入的字符串参数不会为空
忽略空白字符
输入:’hello world’
输出;{h: 1, e: 1, l: 3, o: 2, w: 1, r: 1, d: 1}
1 2 3 4 5 6 7 8 9 10 11 function count (str ) { var map = {}, words = str.split(/\s+/ ); for (var i = 0 ; i < words.length; i++) { for (var j = 0 ; j < words[i].length; j++) { var ch = words[i][j]; map[ch] = map[ch]? map[ch]+1 : 1 ; } } return map; }