1.计时器
实现一个打点计时器,要求
1、从 start 到 end(包含 start 和 end),每隔 100 毫秒 console.log 一个数字,每次数字增幅为 1
2、返回的对象中需要包含一个 cancel 方法,用于停止定时操作
3、第一个数需要立即输出
function count(start, end) {
var f = function () {
if (start <= end) {
console.log(start++);
} else {
clearInterval(timer)
}
}
f();
var timer = setInterval(f, 100);
return {
cancel: function () {
clearInterval(timer)
}
}
}
setTimeout和setInterval的语法相同。都有两个参数,一个是执行代码块,另一个是以毫秒为单位的时间间隔,当过了那个时间段之后就执行那段代码。
区别在于,setInterval在执行完一次代码之后,经过固定时间间隔,还会自动重复执行代码,而setTimeout只执行一次那段代码。
2.流程控制
实现 fizzBuzz 函数,参数 num 与返回值的关系如下:
1、如果 num 能同时被 3 和 5 整除,返回字符串 fizzbuzz
2、如果 num 能被 3 整除,返回字符串 fizz
3、如果 num 能被 5 整除,返回字符串 buzz
4、如果参数为空或者不是 Number 类型,返回 false
5、其余情况,返回参数 num
function fizzBuzz(num) {
if (num === null || num === '' || typeof num !== 'number') {
return false;
}
var result = '';
if (num % 3 === 0) {result += 'fizz';}
if (num % 5 === 0) {result += 'buzz';}
return result || num;
}
3.返回函数
实现函数 functionFunction,调用之后满足如下条件:
1、返回值为一个函数 f
2、调用返回的函数 f,返回值为按照调用顺序的参数拼接,拼接字符为英文逗号加一个空格,即 ', ’
3、所有函数的参数数量为 1,且均为 String 类型
测试:
input: functionFunction(‘Hello’)(‘world’)
output: Hello, world
function functionFunction(str) {
var f = function (s) {
return str + ", " + s;
}
return f;
}
4.使用闭包
实现函数 makeClosures,调用之后满足如下条件:
1、返回一个函数数组 result,长度与 arr 相同
2、运行 result 中第 i 个函数,即 resulti,结果与 fn(arr[i]) 相同
function makeClosures(arr, fn) {
return arr.map(function(item){
return function(){
return fn(item);
}
})
}
不能直接返回fn(item),直接返回的是函数的值,而不是函数了
5.二次封装函数
已知函数 fn 执行需 3 个参数。请实现函数 partial,调用之后满足如下条件:
1、返回一个函数 result,该函数接受一个参数
2、执行 result(str3) ,返回的结果与 fn(str1, str2, str3) 一致
function partial(fn, str1, str2) {
var result = function(str3){
return fn.call(this, str1, str2, str3);
}
return result;
}
6.二次封装函数
实现函数 partialUsingArguments,调用之后满足如下条件:
1、返回一个函数 result
2、调用 result 之后,返回的结果与调用函数 fn 的结果一致
3、fn 的调用参数为 partialUsingArguments 的第一个参数之后的全部参数以及 result 的调用参数
function partialUsingArguments(fn) {
var args = Array.prototype.slice.call(arguments,1)
var result = function () {
return fn.apply(this,args.concat([].slice.call(arguments)))
}
return result;
}
注:除了使用 Array.prototype.slice.call(arguments),也可以简单的使用 [].slice.call(arguments) 来代替。
7.柯里化
已知 fn 为一个预定义函数,实现函数 curryIt,调用之后满足如下条件:
1、返回一个函数 a,a 的 length 属性值为 1(即显式声明 a 接收一个参数)
2、调用 a 之后,返回一个函数 b, b 的 length 属性值为 1
3、调用 b 之后,返回一个函数 c, c 的 length 属性值为 1
4、调用 c 之后,返回的结果与调用 fn 的返回值一致
5、fn 的参数依次为函数 a, b, c 的调用参数
function curryIt(fn) {
var length = fn.length,
args = [];
var result = function (arg){
args.push(arg);
length --;
if(length <= 0 ){
return fn.apply(this, args);
} else {
return result;
}
}
return result;
}
8.二进制转化
获取数字 num 二进制形式第 bit 位的值。注意:
1、bit 从 1 开始
2、返回 0 或 1
3、举例:2 的二进制为 10,第 1 位为 0,第 2 位为 1
function valueAtBit(num, bit) {
var number = num.toString(2);
return number[number.length - bit]
}
注:num.toString(n)可以将数字转化成N进制;
利用坐标取出第n位的数(题目要求为由右至左)
9.属性遍历
找出对象 obj 不在原型链上的属性(注意这题测试例子的冒号后面也有一个空格~)
1、返回数组,格式为 key: value
2、结果数组不要求顺序
function iterate(obj) {
var arr = [];
for(var key in obj){
if(obj.hasOwnProperty(key)){
arr.push(key + ": "+obj[key]);
}
}
return arr;
}
注:for-in来遍历对象中的属性,hasOwnproperty方法能返回一个布尔值,指出一个对象是否具有指定名称的属性。此方法无法检查该对象的原型链中是否具有该属性,该属性必须为对象本身的属性。
10.判断是否符合USD格式
给定字符串 str,检查其是否符合美元书写格式
1、以 $ 开始
2、整数部分,从个位起,满 3 个数字用 , 分隔
3、如果为小数,则小数部分长度为 2
4、正确的格式如:$1,023,032.03 或者 $2.03,错误的格式如:$3,432,12.12 或者 $34,344.3
function isUSD(str) {
return /^\$\d{1,3}(,\d{3})*(\.\d{2})?$/.test(str);
}
11.字符串字符统计
统计字符串中每个字符的出现频率,返回一个 Object,key 为统计字符,value 为出现频率
- 不限制 key 的顺序
- 输入的字符串参数不会为空
- 忽略空白字符
function count(str) {
var obj={};
str=str.replace(/\s/,'');
for(var i=0,length=str.length;i<length;i++){
if(obj.hasOwnProperty(str[i])){
obj[str[i]]++;
}else{
obj[str[i]]=1;
}
}
return obj;
}
12.购物车
HTML模块为一个简化版的购物车,tbody为商品列表,tfoot为统计信息,系统会随机在列表中生成一些初始商品信息
1、请完成add函数,在列表后面显示items商品信息。参数items为{name: String, price: Number}组成的数组
2、请完成bind函数,点击每一行的删除按钮(包括通过add增加的行),从列表中删除对应行
3、请注意同步更新统计信息,价格保留小数点后两位
4、列表和统计信息格式请与HTML示例保持一致
5、不要直接手动修改HTML中的代码
6、不要使用第三方库
<table id="jsTrolley">
<thead><tr><th>名称</th><th>价格</th><th>操作</th></tr></thead>
<tbody>
<tr><td>产品1</td><td>10.00</td><td><a href="javascript:void(0);">删除</a></td></tr>
<tr><td>产品2</td><td>30.20</td><td><a href="javascript:void(0);">删除</a></td></tr>
<tr><td>产品3</td><td>20.50</td><td><a href="javascript:void(0);">删除</a></td></tr>
</tbody>
<tfoot><tr><th>总计</th><td colspan="2">60.70(3件商品)</td></tr></tfoot>
</table>
----------------------------------------------------------------------------------
body,html{
padding: 0;
margin: 0;
font-size: 14px;
color: #000000;
}
table{
border-collapse: collapse;
width: 100%;
table-layout: fixed;
}
thead{
background: #3d444c;
color: #ffffff;
}
td,th{
border: 1px solid #e1e1e1;
padding: 0;
height: 30px;
line-height: 30px;
text-align: center;
}
function add(items) {
var str = '';
var tbody = document.querySelector('tbody');
for (var i = 0; i < items.length; i++) {
str += `<tr><td>` + items[i].name + `</td><td>`
+ items[i].price.toFixed(2)
+ `</td><td><a href="javascript:void(0);">删除</a></td></tr>`;
}
tbody.innerHTML += str;
count();
}
function bind() {
var tbody = document.querySelector('tbody');
var del = tbody.querySelectorAll('a');
tbody.addEventListener('click', function (event) {
var el = event.target;
if (el.tagName.toLowerCase() === 'a') {
tbody.removeChild(el.parentNode.parentNode);
count();
}
});
}
function count() {
var tbody = document.querySelector('tbody');
var tr = tbody.querySelectorAll('tr');
var tfoot = document.querySelector('tfoot');
var td = tfoot.querySelector('td');
var sum = 0;
for (var i = 0; i < tr.length; i++) {
sum += parseFloat(tr[i].children[1].innerHTML);
}
td.innerHTML = sum.toFixed(2) + '(' + tr.length + '件商品)';
}
13.判断斐波那契数组
根据题目要求,判断数组参数中的值是否符合斐波那契数列,该数列指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、…。在数学上,斐波那契数列以如下被以递推的方法定义:F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*)
注:[0,1,1]为最短有效斐波那契数组
思路:
首先判断数组参数的长度是否小于3,第一、二项的值是否分别为0、1,如果其中一项不符合,那么返回false
遍历数组参数,从第三项开始,判断该项的值是否符合F(n)=F(n - 1)+F(n - 2),是则continue,否则返回false
当数组遍历完成时返回true
const _isFibonacci = array => {
if(array.length < 3 || array[0] !== 0 || array[1] !== 1) return false
for(let i=2 ; i<array.length ; i++) {
if(array[i] === array[i-1] + array[i-2]) continue
return false
}
return true
}
14.数组扁平化
请补全JavaScript代码,要求将数组参数中的多维数组扩展为一维数组并返回该数组。
注意:数组参数中仅包含数组类型和数字类型
const _flatten = arr => {
let newArr=[]
arr.forEach(item=>{
if(Array.isArray(item)){
newArr=newArr.concat(_flatten(item))
}else{
newArr.push(item)
}
})
return newArr
}
Array.isArray() 用于确定传递的值是否是一个 Array。
15.数组过滤
请补全JavaScript代码,要求根据下拉框选中的条件变换重新渲染列表中展示的商品,且只展示符合条件的商品。
注意:
1.必须使用DOM0级标准事件(onchange)
2.建议使用ES6的filter方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<select name="" id="">
<option value="0">请选择销量范围</option>
<option value="1"><100</option>
<option value="2">100~500</option>
<option value="3">>500</option>
</select>
<ul>
<li>牛客logo马克杯</li>
<li>无盖星空杯</li>
<li>老式茶杯</li>
<li>欧式印花杯</li>
</ul>
<script>
var cups = [
{ type: 1, price: 100, color: 'black', sales: 60, name: '牛客logo马克杯' },
{ type: 2, price: 40, color: 'blue', sales: 100, name: '无盖星空杯' },
{ type: 4, price: 60, color: 'green', sales: 200, name: '老式茶杯' },
{ type: 3, price: 50, color: 'green', sales: 600, name: '欧式印花杯' }
]
var select = document.querySelector('select');
var ul = document.querySelector('ul');
// 补全代码
select.onchange = function(){
var index = select.selectedIndex;
function show(arr){
let list = '';
arr.forEach(function(item){
list +=`<li>${item.name}</li>`
})
ul.innerHTML = list;
}
function choice(cups,index){
let resArr = cups.filter(function(item){
if(index ==1){
return item.sales <100;
}else if(index ==2){
return item.sales >=100 && item.sales <=500;
}else if(index ==3){
return item.sales >500
}
})
return resArr;
}
show(choice(cups,index))
}
</script>
</body>
</html>
16 全选
请补全JavaScript代码,实现以下效果:
- 选中"全选"框,以下所有选项全部勾选。
- 把"全选"框从选中状态勾选成未选中状态,其他复选框全部取消选中效果。
- 当其他复选框全部选中,"全选框"为选中状态。
- 当其他复选框有一个未选中,"全选框"取消选中状态。
注意: - 必须使用DOM0级标准事件(onchange)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<style>
ul {
list-style: none;
}
</style>
<body>
<ul>
<li>全选<input type='checkbox' id='all'></li>
<li>Java<input type='checkbox' class='item'></li>
<li>javaScript<input type='checkbox' class='item'></li>
<li>C++<input type='checkbox' class='item'></li>
<li>python<input type='checkbox' class='item'></li>
<li>.net<input type='checkbox' class='item'></li>
</ul>
<script>
// 补全代码
var all = document.querySelector('#all');
var options = Array.from(document.querySelectorAll('.item'));
all.onchange = function(){
options.forEach(x =>{x.checked = all.checked})
}
options.forEach((item)=>{
item.onchange = function(){
if(!this.checked){
all.checked = false;
}else{
if(options.every(x => x.checked)){
all.checked = true;
}else{
all.checked = false;
}
}
}
})
</script>
</body>
</html>
Array.from() 方法对一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。
querySelectorAll!!querySelectorAll!!querySelectorAll!!
17.Proxy计数器
请给参数对象添加拦截代理功能,并返回这个代理,要求每当通过代理调用该对象拥有的属性时,"count"值加1,否则减1。
let count = 0
const _proxy = object => {
let proxy = new Proxy(object, {
get: function (target, propKey) {
if (propKey in target) {
count++
} else {
count--
}
}
})
return proxy;
function}
18.监听对象
- 监听对象属性的变化
- 当"person"对象的属性发生变化时,页面中与该属性相关的数据同步更新
注意: - 必须使用Object.defineProperty实现且触发set方法时更新视图
- 可以使用预设代码"_render"函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<style>
ul {
list-style: none;
}
</style>
<ul></ul>
<script>
var ul = document.querySelector('ul');
var person = { sex: '男', age: '25', name: '王大锤', height: 28, weight: 32 };
const _render = element => {
var str = `<li>姓名:<span>${person.name}</span></li>
<li>性别:<span>${person.sex}</span></li>
<li>年龄:<span>${person.age}</span></li>
<li>身高:<span>${person.height}</span></li>
<li>体重:<span>${person.weight}</span></li>`
element.innerHTML = str;
}
_render(ul);//补全代码
function Observe(target) {
if (typeof target !== 'object' || target == null) {
return target
}
for (var key in target) {
defineReactive(target, key, target[key])
}
}
function defineReactive(target, key, value) {
Object.defineProperty(target, key, {
get: function () {
return value
},
set: function (newVal) {
if (newVal !== value) {
value = newVal
_render(ul)
}
}
})
}
Observe(person)
</script>
</body>
</html>
19.接口
请补全JavaScript代码,完成函数的接口功能。要求如下:
- 函数接收两种类型的参数,分别为"get?“和"update?name=xxx&to=yyy”,“name”、"to"为参数,“xxx”、"yyy"分别为参数对应的值。
- 当参数为"get?"时,返回data数据
- 当参数为"update?name=xxx&to=yyy"时,将data中所有"name"为"xxx"的项,更改为"name"值为"yyy"
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
</head>
<body>
<script type="text/javascript">
let data = [
{name: 'nowcoder1'},
{name: 'nowcoder2'}
]
const _api = string => {
// 补全代码
let toArr = string.split('?');
if(toArr[0]=='get'){
return data;
} else {
let b = {};
let a = toArr[1].split('&');
a.forEach(item =>{
let [key, value]=item.split('=');
b[key]=value;
})
data.forEach((item,index) =>{
if(item.name==b.name){
data[index].name = b.to;
}
})
}
}
</script>
</body>
</html>
20.高频数据类型
请补全JavaScript代码,要求找到参数数组中出现频次最高的数据类型,并且计算出出现的次数,要求以数组的形式返回。
注意:
- 基本数据类型之外的任何引用数据类型皆为"object"
- 当多种数据类型出现频次相同时将结果拼接在返回数组中,出现次数必须在数组的最后
核心步骤:
1.声明一个临时对象,用于存储数据类型和该数据类型出现的频次
2.声明一个数组,用于返回结果
3.声明一个数字,用于保存出现最高频的数据类型次数
4.通过遍历数组,更新临时对象的内容并且修改数字
5.最后通过遍历对象,判断是否存在某个数据类型出现的频次和当前最高频次的数据类型出现次数相等并进行拼接
const _findMostType = array => {
let tem = {};
let arr = [];
let num = 0;
for (key of array) {
let type = typeof key;
if (tem[type]) {
tem[type]++;
} else {
tem[type] = 1;
}
num = tem[type] > num ? tem[type] : num
}
for (key in tem) {
arr = tem[key] === num ? [...arr, key] : arr
}
return [...arr, num]
}
21.字体高亮
请补全JavaScript代码,实现一个搜索字体高亮的效果。要求如下:
- 在input框中输入要搜索的内容,当点击查询按钮时,被搜索的字体样式变为加粗,背景色变为’yellow’
- 重新输入搜索文字,点击查询按钮时,去掉上一次的搜索效果,高亮显示效果只加在本次搜索文字上
- 如果搜索不到相关内容,清除之前的效果
注意: - 需要加粗的文字请使用b标签包裹
- 必须使用DOM0级标准事件(onclick)
<body>
<input type="text">
<button style="margin-right: 80px">查询</button>
<div class="text" style="margin-top: 70px">
牛客网隶属于北京牛客科技有限公司,牛客网成立于 2014 年 9
月,是以科技和创新驱动的教育科技公司。牛客网坚持以前沿技术服务于技术、以人工智能和大数据提升学习效率,专注探索在线教育创新模式,致力于为技术求职者提供能力提升解决方案,同时为企业级用户提供更高效的招聘解决方案,并为二者搭建桥梁,构建从学习到职业的良性生态圈。
发展至今,牛客网在技术类求职备考、社群交流、企业招聘服务等多个垂直领域影响力均在行业中遥遥领先,产品矩阵包括IT题库、在线编程练习、线上课程、交流社区、竞赛平台、笔面试服务、ATS系统等,用户覆盖全国高校百万IT学习者并在高速增长中,同时也为京东、百度、腾讯、滴滴、今日头条、华为等200多家企业提供校园招聘、编程竞赛等线上服务,并收获良好口碑。
</div>
<script>
var text = document.querySelector(".text");
var search = document.querySelector("input");
const btn = document.querySelector("button");
btn.onclick = () => {
// 补全代码
if (text.innerHTML.indexOf(search.value) != -1) {
text.innerHTML = text.innerHTML.replace(new RegExp(search.value, 'g'), `<b style='background-color:yellow; color:red;'>${search.value}</b>`)
} else {
let Btags = document.querySelectorAll("b");
for (let index = 0; index < Btags.length; index++) {
Btags[index].style.cssText = "background-color:transparent; color: unset; font-weight: unset;";
}
}
}
</script>
</body>
22.虚拟DOM
请补全JavaScript代码,要求将对象参数转换为真实的DOM结构并返回。
注意:
tag为标签名称、props为属性、children为子元素、text为标签内容
根据题目要求,将虚拟DOM转换为真实DOM结构并返回,核心步骤有:
1.析构对象参数中的tag、props、children、text值
2.当tag的数据类型为”string“时,通过tag标签创建新节点并且挂载在vnode对象参数的el属性上
3.再通过setAttribute函数给vnode.el节点设置属性
4.然后通过appendChild、createTextNode将当前节点对象的text内容插入vnode.el节点上
5.最后通过createElm函数递归children数组重复以上过程
6.当tag的数据类型不为string时,直接通过createTextNode创建文本节点
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<script>
var vnode = {
tag: 'ul',
props: {
class: 'list'
},
text: '',
children: [
{
tag: "li",
props: {
class: "item"
},
text: '',
children: [
{
tag: undefined,
props: {},
text: '牛客网',
children: []
}
]
},
{
tag: "li",
props: {},
text: '',
children: [
{
tag: undefined,
props: {},
text: 'nowcoder',
children: []
}
]
}
]
}
const _createElm = vnode => {
// 补全代码
let { tag, props, children, text } = vnode;
if (typeof tag == "string") {
vnode.el = document.createElement(tag);
_setAttr(vnode.el, props)
vnode.el.appendChild(document.createTextNode(text))
children.forEach(child => {
vnode.el.appendChild(_createElm(child))
})
} else {
vnode.el = document.createTextNode(text)
}
return vnode.el;
}
const _setAttr = (elem, attrs) => {
for (key in attrs) {
elem.setAttribute(key, attrs[key])
}
}
</script>
</body>
</html>
23.数组去重
为 Array 对象添加一个去除重复项的方法
Set数据结构类似于数组,但里面的成员都是唯一的。
判断是否唯一的标准基本等同于===
唯一的区别在于,三等符号判断时NaN与NaN不相等,但Set会认为它们相等并去重。
由于Set只是类似数组,所以要用Array.from返回一个真正的数组。
Array.prototype.uniq = function () {
return Array.from(new Set(this))
}
24.斐波那契数列
用 JavaScript 实现斐波那契数列函数,返回第n个斐波那契数。 f(1) = 1, f(2) = 1 等
function fibonacci(n) {
if(n ==1 || n==2){
return 1;
}else{
return fibonacci(n-1) + fibonacci(n-2)
}
}