一、入门
1、dom 节点查找
描述:查找两个节点的最近的一个共同父节点,可以包括节点自身
输入描述:oNode1 和 oNode2 在同一文档中,且不会为相同的节点
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<div id="root">
<div id="parent1">
<div id="child1"></div>
<div id="parent2">
<div id="child2"></div>
</div>
</div>
</div>
<!-- 填写标签 -->
<script type="text/javascript">
function commonParentNode(oNode1, oNode2) {
const ancestors1 = new Set();
// 从oNode1向上遍历父节点链,并将每个父节点添加到Set中
let currentNode = oNode1;
while (currentNode) {
ancestors1.add(currentNode);
currentNode = currentNode.parentNode;
}
// 从oNode2向上遍历父节点链,检查每个父节点是否在ancestors1中存在
currentNode = oNode2;
while (currentNode) {
if (ancestors1.has(currentNode)) {
return currentNode;// 如果找到共同的父节点,返回它
}
currentNode = currentNode.parentNode;
}
}
const node1 = document.getElementById('child1');
const node2 = document.getElementById('child2');
const commonAncestor = commonParentNode(node1, node2);
console.log(commonAncestor)//输出dom结构parent1
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<div id="root">
<div id="parent1">
<div id="child1"></div>
<div id="parent2">
<div id="child2"></div>
</div>
</div>
</div>
<!-- 填写标签 -->
<script type="text/javascript">
function commonParentNode(oNode1, oNode2) {
//无须关心谁包含谁,只要当前节点的父节点包含另一个节点就行
for(;oNode1;oNode1=oNode1.parentNode){
if(oNode1.contains(oNode2)){
return oNode1;
}
}
}
const node1 = document.getElementById('child1');
const node2 = document.getElementById('child2');
const commonAncestor = commonParentNode(node1, node2);
console.log(commonAncestor)
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<div id="root">
<div id="parent1">
<div id="child1">
</div>
<div id="parent2">
<div id="child2"></div>
</div>
</div>
</div>
<!-- 填写标签 -->
<script type="text/javascript">
//验证一个节点是否包含另一个节点,否则拿到父节点重新进行验证
function commonParentNode(oNode1, oNode2) {
if(oNode1.contains(oNode2)){
return oNode1;
}else{
return commonParentNode(oNode1.parentNode,oNode2);
}
}
const node1 = document.getElementById('child1');
const node2 = document.getElementById('child2');
const commonAncestor = commonParentNode(node1, node2);
console.log(commonAncestor)
</script>
</body>
</html>
2、根据包名,在指定空间中创建对象
描述:根据包名,在指定空间中创建对象
输入描述:namespace({a: {test: 1, b: 2}}, 'a.b.c.d')
输出描述:{a: {test: 1, b: {c: {d: {}}}}}
function namespace(namespaceObj, sPackage) {
const arr = sPackage.split('.');
let currentObj = namespaceObj;
for(let i = 0;i<arr.length ;i++) {
// 如果不是对象,则使它成为对象
if(typeof currentObj[arr[i]] != 'object') {
currentObj[arr[i]] = {};
}
currentObj = currentObj[arr[i]];
}
return namespaceObj;
}
// 示例用法
const namespaceObj = {a: {test: 1, b: 2}};
const result = namespace(namespaceObj, 'a.b.c.d');
console.log(result);// 输出: { a: { test: 1, b: { c: { d: {} } } } }
3、斐波那契数列
描述:用 JavaScript 实现斐波那契数列函数,返回第n个斐波那契数。 f(1) = 1, f(2) = 1 等
function fibonacci(n) {
if(n<=2){
return 1
} else{
return fibonacci(n-1) + fibonacci(n-2)
}
}
console.log(fibonacci(1)); // 输出: 1
console.log(fibonacci(2)); // 输出: 1
console.log(fibonacci(3)); // 输出: 2
console.log(fibonacci(4)); // 输出: 3
console.log(fibonacci(5)); // 输出: 5
console.log(fibonacci(10)); // 输出: 55
function fibonacci(n) {
if (n <= 0) {
throw new Error("Input should be a positive integer.");
}
if (n === 1 || n === 2) {
return 1;
}
var num1 = 1, num2 = 1;
for (var i = 3; i <= n; i++) {
var temp = num2;
num2 += num1;
num1 = temp;
}
return num2;
}
console.log(fibonacci(1)); // 输出: 1
console.log(fibonacci(2)); // 输出: 1
console.log(fibonacci(3)); // 输出: 2
console.log(fibonacci(4)); // 输出: 3
console.log(fibonacci(5)); // 输出: 5
console.log(fibonacci(10)); // 输出: 55
4、计数
描述:统计数组 arr 中值等于 item 的元素出现的次数
示例:
输入:[1, 2, 4, 4, 3, 4, 3], 4
输出:3
function count(arr, item) {
let itemArr = arr.filter((num)=>{
return num===item
})
return itemArr.length
}
let arr =[1, 2, 4, 4, 3, 4, 3];
let item = 4;
count(arr, item);
function count(arr, item) {
var num = 0;
arr.forEach(function(a){
if(a == item){
num++;
}
});
return num;
}
let arr =[1, 2, 4, 4, 3, 4, 3];
let item = 4;
count(arr, item);
function count(arr, item) {
let sum = 0
for (let i = 0; i < arr.length; i++) {
if(item === arr[i]){
sum++
}
}
return sum
}
let arr =[1, 2, 4, 4, 3, 4, 3];
let item = 4;
count(arr, item);
function count(arr, item) {
return arr.filter(e=>e == item).length
}
let arr =[1, 2, 4, 4, 3, 4, 3];
let item = 4;
count(arr, item);
5、函数传参
描述:将数组 arr 中的元素作为调用函数 fn 的参数
示例:
输入:function (greeting, name, punctuation) {return greeting + ', ' + name + (punctuation || '!');},
['Hello', 'Ellie', '!']
输出:Hello, Ellie!
function argsAsArray(fn, arr) {
return fn.apply(null, arr); //
}
let fn = function (greeting, name, punctuation) {
return greeting + ', ' + name + (punctuation || '!');
}
let arr = ['Hello', 'Ellie', '!'];
console.log(argsAsArray(fn, arr));
let fn = function (greeting, name, punctuation) {
return greeting + ', ' + name + (punctuation || '!');
}
let arr = ['Hello', 'Ellie', '!'];
// 直接使用扩展语法调用函数
console.log(fn(...arr));
6、函数的上下文
描述:将函数 fn 的执行上下文改为 obj 对象
示例
输入:function () {return this.greeting + ', ' + this.name + '!!!';}, {greeting: 'Hello', name: 'Rebecca'}
输出:Hello, Rebecca!!!
function speak(fn, obj) {
return fn.apply(obj)
}
let fn = function () {return this.greeting + ', ' + this.name + '!!!';}
let obj = {greeting: 'Hello', name: 'Rebecca'}
console.log(speak(fn, obj))
function speak(fn, obj) {
return fn.call(obj)
}
let fn = function () {return this.greeting + ', ' + this.name + '!!!';}
let obj = {greeting: 'Hello', name: 'Rebecca'}
console.log(speak(fn, obj))
function speak(fn, obj) {
return fn.bind(obj)()
}
let fn = function () {return this.greeting + ', ' + this.name + '!!!';}
let obj = {greeting: 'Hello', name: 'Rebecca'}
console.log(speak(fn, obj))
function speak(fn, obj) {
obj.fn = fn
return obj.fn()
}
let fn = function () {return this.greeting + ', ' + this.name + '!!!';}
let obj = {greeting: 'Hello', name: 'Rebecca'}
console.log(speak(fn, obj))
call()、bind()、apply()的用法,改变this的指向,区别在于:f.bind(obj, arg1, arg2,...)(),bind()方法创建一个新的函数,故需要自己调用;f.call(obj, arg1, arg2...),call()方法在调用函数后会返回函数的执行结果,call可以接受多个参数;f.apply(obj, [arg1, arg2, .]),apply()方法在调用函数后会返回函数的执行结果,apply可以接受一个数组参数列表。
7、二次封装函数
描述:
已知函数 fn 执行需要 3 个参数。请实现函数 partial,调用之后满足如下条件:
1、返回一个函数 result,该函数接受一个参数
2、执行 result(str3) ,返回的结果与 fn(str1, str2, str3) 一致
示例1
输入:var sayIt = function(greeting, name, punctuation) { return greeting + ', ' + name + (punctuation || '!'); }; partial(sayIt, 'Hello', 'Ellie')('!!!');
输出:
Hello, Ellie!!!
// 匿名函数,默认this绑定global,与bind的第一个参数为this时效果一样。
function partial(fn, str1, str2) {
return function(str3){
return fn(str1,str2,str3);
}
}
let fn = function(greeting, name, punctuation) {
return greeting + ', ' + name + (punctuation || '!');
};
partial(fn, 'Hello', 'Ellie')('!!!');
function partial(fn, str1, str2) {
function result(str3) {
return fn.call(this, str1, str2, str3);
}
return result;
}
let fn = function(greeting, name, punctuation) {
return greeting + ', ' + name + (punctuation || '!');
};
partial(fn, 'Hello', 'Ellie')('!!!');
function partial(fn, str1, str2) {
function result(str3) {
return fn.apply(this, [str1, str2, str3]);
}
return result;
}
let fn = function(greeting, name, punctuation) {
return greeting + ', ' + name + (punctuation || '!');
};
partial(fn, 'Hello', 'Ellie')('!!!');
// 这个bind会生成一个新函数(对象), 它的str1, str2参数都定死了, str3未传入, 一旦传入就会执行
function partial(fn, str1, str2) {
return fn.bind(this, str1, str2); ;
}
let fn = function(greeting, name, punctuation) {
return greeting + ', ' + name + (punctuation || '!');
};
partial(fn, 'Hello', 'Ellie')('!!!');
function partial(fn, str1, str2) {
function result(str3) {
return fn.bind(this, str1, str2)(str3);
}
return result;
}
let fn = function(greeting, name, punctuation) {
return greeting + ', ' + name + (punctuation || '!');
};
partial(fn, 'Hello', 'Ellie')('!!!');
var partial = (fn, str1, str2) => str3 => fn(str1, str2, str3);
//传统的函数表达式写法
//var partial = function(fn, str1, str2) {
// return function(str3) {
// return fn(str1, str2, str3);
// };
//};
let fn = function(greeting, name, punctuation) {
return greeting + ', ' + name + (punctuation || '!');
};
partial(fn, 'Hello', 'Ellie')('!!!');
8、使用 arguments
描述:函数 useArguments 可以接收 1 个及以上的参数。请实现函数 useArguments,返回所有调用参数相加后的结果。本题的测试参数全部为 Number 类型,不需考虑参数转换。
示例
输入:1, 2, 3, 4
输出:10
function useArguments() {
let num = 0;
for (let index = 0; index < arguments.length; index++) {
num += arguments[index];
}
return num;
}
let arr =[1, 2, 3, 4];
console.log(useArguments(1, 2, 3, 4))
function useArguments(...args) {
return args.reduce((count, num) => count + num, 0);
}
console.log(useArguments(1, 2, 3, 4)); // 输出 10
function useArguments() {
return Array.prototype.reduce.call(arguments,function(acc,cur){
return acc+=cur
})
}
console.log(useArguments(1, 2, 3, 4))
9、柯里化
柯里化是将一个接收多个参数的函数,转变为一系列接收一个单一参数的函数的技术。每个这样的函数都返回下一个待调用的函数,直到最后一个函数接收完所有参数并返回最终结果。
描述:
已知 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 的调用参数
示例
输入:var fn = function (a, b, c) {return a + b + c}; curryIt(fn)(1)(2)(3);
输出:6
//curryIt 是一个高阶函数,它接收一个函数 fn 作为参数,并返回一个新的函数 fun。
function curryIt(fn) {
return function fun(a){
//fn.length 返回 fn 函数所声明的参数个数。如果 fn 只有一个参数,那么 curryIt 返回的函数可以直接调用 fn 并传入参数 a
if(fn.length===1)return fn(a)
fn=fn.bind(this,a)
return fun
}
}
var fn = function (a, b, c) {return a + b + c};
console.log(curryIt(fn)(1)(2)(3))
//curryIt(fn)(1):fn 的参数个数是 3,不等于 1,所以使用 bind 创建一个新函数,这个新函数将 1 作为第一个参数预置给 fn,并返回 fun 函数。
//curryIt(fn)(1)(2):再次调用返回的 fun 函数,这次传入 2。同样,fn 的参数个数仍然不是 1,所以再次使用 bind,这次将 2 作为第二个参数预置给 fn(第一个参数已经是 1 了),并返回 fun 函数。
//curryIt(fn)(1)(2)(3):最后,传入 3。此时,fn 的所有参数都已经满足(因为 fn 需要 3 个参数),所以直接调用 fn(1, 2, 3) 并返回结果 6。
function curryIt(fn) {
return function a(x1){
return function b(x2){
return function c(x3){
return fn(x1, x2, x3);
}
}
}
}
var fn = function (a, b, c) {return a + b + c};
console.log(curryIt(fn)(1)(2)(3))
//curryIt(fn)(1):调用 curryIt 返回的函数 a,并传入 1。返回函数 b,此时 b 的闭包中包含了 x1 = 1。
//curryIt(fn)(1)(2):调用函数 b,并传入 2。返回函数 c,此时 c 的闭包中包含了 x1 = 1 和 x2 = 2。
//curryIt(fn)(1)(2)(3):调用函数 c,并传入 3。此时,所有参数都已经满足,所以直接调用 fn(1, 2, 3) 并返回结果 6。
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;
}
var fn = function (a, b, c) {return a + b + c};
console.log(curryIt(fn)(1)(2)(3))
//curryIt(fn)(1):调用 result 函数,并传入 1。args 变为 [1],length 变为 2。返回 result 函数本身。
//curryIt(fn)(1)(2):再次调用 result 函数,并传入 2。args 变为 [1, 2],length 变为 1。返回 result 函数本身。
//curryIt(fn)(1)(2)(3):再次调用 result 函数,并传入 3。args 变为 [1, 2, 3],length 变为 0。此时,所有参数都已经满足,所以调用 fn.apply(this, [1, 2, 3]),即 fn(1, 2, 3),并返回结果 6。
10、二进制转换
描述:给定二进制字符串,将其换算成对应的十进制数字
示例
输入:'11000000'
输出:192
function base10(str) {
//parseInt(string, radix) 解析一个字符串并返回指定基数的十进制整数,
//radix 是2-36之间的整数,表示被解析字符串的基数。
return parseInt(str,2); //将str看做二进制数,返回十进制数
}
let num = '11000000';
console.log(base10(num))
function base10(str) {
let arr = str.split("").reverse(); //先将数据进行处理 将个位翻转到第一个去
let result = 0;
for (let i = 0; i < arr.length; i++) {//二进制转十进制,是从个位开始运算再依次与后面相加
result = result + arr[i] * Math.pow(2, i); //Math.pow(2, i)代表求2的i次方,在二进制数中,每一位的权重是 2 的幂,从最低位(个位)开始,权重分别为 2
}
return result;
}
let num = '11000000';
console.log(base10(num))
11、乘法
描述:求 a 和 b 相乘的值,a 和 b 可能是小数,需要注意结果的精度问题
示例
输入:3, 0.0001
输出:0.0003
function multiply (a, b) {
var f1 = 1, f2 = 1;
// 如果存在小树点则乘以他的0的个数f1,f2分别存储a,b的倍数最后先算a*b扩大的在除以抵消掉
if (String(a).indexOf(".") != -1) {
f1 = String(a).length - (String(a).indexOf(".")+ 1)
f1 = Math.pow(10, f1)
a = a * f1
}
if (String(b).indexOf(".") != -1) {
f2 = String(b).length - (String(b).indexOf(".") + 1)
f2 = Math.pow(10, f2)
b = b * f2
}
return a * b / f1 / f2
}
let a = 10.097;
let b = 10.102;
console.log(multiply(a, b)); // 输出正确的乘积结果
function multiply(a, b) {
debugger
a = a.toString();
b = b.toString();
alen = a.indexOf(".") == -1 ? 1 : Math.pow(10, a.length - (a.indexOf(".")+ 1));
blen = b.indexOf(".") == -1 ? 1 : Math.pow(10, b.length - (b.indexOf(".")+ 1));
return (a * alen) * (b * blen) / alen / blen
}
let a = 10.097;
let b = 10.102;
console.log(multiply(a, b)); // 输出正确的乘积结果
function multiply(a, b) {
a = a.toString();
b = b.toString();
var aLen = a.substring(a.indexOf(".")+1).length;
var bLen = a.substring(a.indexOf(".")+1).length;
return (a * Math.pow(10,aLen)) * (b * Math.pow(10,bLen)) / Math.pow(10,aLen+bLen);
}
let a = 10.097;
let b = 10.102;
console.log(multiply(a, b)); // 输出正确的乘积结果
function multiply(a, b) {
debugger
// 计算a和b的小数位数
let decimalPlacesA = ('' + a).split('.')[1] ? ('' + a).split('.')[1].length : 0;
let decimalPlacesB = ('' + b).split('.')[1] ? ('' + b).split('.')[1].length : 0;
// 计算放大倍数
let factorA = Math.pow(10, decimalPlacesA);
let factorB = Math.pow(10, decimalPlacesB);
// 将a和b转换为整数进行乘法运算
let aInt = a * factorA;
let bInt = b * factorB;
// 计算乘积并还原小数位
let product = (aInt * bInt) / (factorA * factorB);
return product;
}
let a = 10.097;
let b = 10.102;
console.log(multiply(a, b)); // 输出正确的乘积结果
12、改变上下文
描述:将函数 fn 的执行上下文改为 obj,返回 fn 执行后的值
示例
输入:function() {return this.greeting + ', ' + this.name + '!'; },{name: 'Rebecca', greeting: 'Yo' }
输出:Yo, Rebecca!
function alterContext(fn, obj) {
return fn.call(obj)
}
let fn =function() {return this.greeting + ', ' + this.name + '!'; };
let obj ={name: 'Rebecca', greeting: 'Yo' };
console.log(alterContext(fn, obj) );
function alterContext(fn, obj) {
return fn.apply(obj)
}
let fn =function() {return this.greeting + ', ' + this.name + '!'; };
let obj ={name: 'Rebecca', greeting: 'Yo' };
console.log(alterContext(fn, obj) );
function alterContext(fn, obj) {
return fn.bind(obj)();
}
let fn =function() {return this.greeting + ', ' + this.name + '!'; };
let obj ={name: 'Rebecca', greeting: 'Yo' };
console.log(alterContext(fn, obj) );
function alterContext(fn, obj) {
obj.fn = fn
return obj.fn()
}
let fn =function() {return this.greeting + ', ' + this.name + '!'; };
let obj ={name: 'Rebecca', greeting: 'Yo' };
console.log(alterContext(fn, obj) );
13、批量改变对象的属性
描述:给定一个构造函数 constructor,请完成 alterObjects 方法,将 constructor 的所有实例的 greeting 属性指向给定的 greeting 变量。
示例:
输入:var C = function(name) {this.name = name; return this;};
var obj1 = new C('Rebecca');
alterObjects(C, 'What's up');
obj1.greeting;
输出:What's up
function alterObjects(Constructor, greeting) {
Constructor.prototype.greeting = greeting;
}
var C = function(name) {
this.name = name;
return this;
};
var instance = new C('Rebecca');
alterObjects(C, 'What's up');
console.log(instance .greeting)
14、判断是否包含数字
描述:给定字符串 str,检查其是否包含数字,包含返回 true,否则返回 false
示例:
输入:'abc123'
输出:true
function containsNumber(str) {
debugger
for(let i= 0; i< str.length; i++) {
if(!isNaN(Number(str[i]))) return true
}
return false
}
let str ="abc123";
console.log(containsNumber(str))
function containsNumber(str) {
const reg = /([0-9])/
return reg.test(str)
}
let str ="abc123";
console.log(containsNumber(str))
15、判断是否以元音字母结尾
描述:
给定字符串 str,检查其是否以元音字母结尾
1、元音字母包括 a,e,i,o,u,以及对应的大写
2、包含返回 true,否则返回 false
示例
输入:'gorilla'
输出:true
function endsWithVowel(str) {
debugger
let arr = 'aeiou';
let end = str[str.length-1];
return arr.indexOf(end)>-1||arr.toUpperCase().indexOf(end)>-1?true:false;
}
let str = 'gorillO';
console.log(endsWithVowel(str));
function endsWithVowel(str) {
let reg = /[aeiou]$/i;// $表示以什么结尾, i表示不区分大小写搜索
return reg.test(str);
}
let str = 'gorilla';
console.log(endsWithVowel(str));
二、简单
1、获取字符串的长度
描述:如果第二个参数 bUnicode255For1 === true,则所有字符长度为 1,否则如果字符 Unicode 编码 > 255 则长度为 2(它的意思是如果传进来的参数(也就是bUnicode255For1)是传的true,那么字符串中每个字符按照1的长度来计算;如果传进来的是flase,那么再对每一个字符进行判断,如果它们的unicode编码>255(a=97),那么该字符就按照2的长度来计算,否则长度为1)
示例:
输入:'hello world, 牛客', false
输出:17
function strLength(s, bUnicode255For1) {
let len = s.length
if(!bUnicode255For1){
for(let i in s){
if(s.charCodeAt(i)>255)len++
}
}
return len
}
let s="hello world, 牛客";
console.log(strLength(s, false));
function strLength(s, bUnicode255For1) {
if (bUnicode255For1) {
return s.length;
} else {
for (var i = 0, length = 0; i < s.length; i++) {
if (s.charCodeAt(i) > 255) {
length = length + 2;
} else {
length++;
}
}
return length;
}
}
let s="hello world, 牛客";
console.log(strLength(s, false));
2、 返回函数
描述:
实现函数 functionFunction,调用之后满足如下条件:
1、返回值为一个函数 f
2、调用返回的函数 f,返回值为按照调用顺序的参数拼接,拼接字符为英文逗号加一个空格,即 ', '
3、所有函数的参数数量为 1,且均为 String 类型
示例
输入:functionFunction('Hello')('world')
输出:Hello, world
function functionFunction(str1) {
return function(str2){
return str1+", "+str2
}
}
functionFunction("hello")("world");
function functionFunction(str) {
let f = function(s) {
return str + ', ' + s
}
return f
}
functionFunction("hello")("world");
function functionFunction(str) {
debugger
let args = [].slice.call(arguments)
return function() {
args = args.concat([].slice.call(arguments))
return args.join(', ')
}
}
functionFunction("hello")("world");
3、使用 apply 调用函数
描述:
实现函数 callIt,调用之后满足如下条件
1、返回的结果为调用 fn 之后的结果
2、fn 的调用参数为 callIt 的第一个参数之后的全部参数
function callIt(fn, ...args) {
return fn.apply(null, args);
}
function add(a, b) {
return a + b;
}
console.log(callIt(add, 5, 3)); // 输出: 8
function callIt(fn) {
return fn.apply(this,[].slice.call(arguments,1))
}
function add(a, b) {
return a + b;
}
console.log(callIt(add, 5, 3)); // 输出: 8
function callIt(fn) {
var arr=[];
for(var i=1;i<arguments.length;i++){
arr.push(arguments[i])
}
return fn.apply(callIt,arr)
}
function add(a, b) {
return a + b;
}
console.log(callIt(add, 5, 3)); // 输出: 8
4、二次封装函数
描述:
实现函数 partialUsingArguments,调用之后满足如下条件:
1、返回一个函数 result
2、调用 result 之后,返回的结果与调用函数 fn 的结果一致
3、fn 的调用参数为 partialUsingArguments 的第一个参数之后的全部参数以及 result 的调用参数
function partialUsingArguments(fn, ...initialArgs) {
debugger
return function(...laterArgs) {
const allArgs = initialArgs.concat(laterArgs);
return fn.apply(this, allArgs);
};
}
function sum(a, b, c) {
return a + b + c;
}
console.log(partialUsingArguments(sum, 1, 2)(3)); // 输出: 6
function partialUsingArguments(fn) {
let args1 = Array.prototype.slice.call(arguments, 1)
return function() {
let args2 = Array.prototype.slice.call(arguments, 0)
return fn.apply(this, args1.concat(args2))
}
}
function sum(a, b, c,d) {
return a + b + c+d;
}
console.log(partialUsingArguments(sum, 1, 2)(3,4)); // 输出:10
function partialUsingArguments(fn) {
var arr = [].slice.call(arguments, 1);
return result = function(){
return fn.apply(this, arr.concat([].slice.call(arguments)) );
};
}
function sum(a, b, c,d) {
return a + b + c+d;
}
console.log(partialUsingArguments(sum, 1, 2)(3,4)); // 输出: 10
5、二进制转换
描述:
获取数字 num 二进制形式第 bit 位的值。注意:
1、bit 从 1 开始
2、返回 0 或 1
3、举例:2 的二进制为 10,第 1 位为 0,第 2 位为 1
示例
输入:128, 8
输出:1
function valueAtBit(num, bit) {
debugger
if(bit < 1) return
var newN = num.toString(2)
return Number(newN.slice(newN.length-bit,newN.length-bit+1))
}
let num = 128
console.log(valueAtBit(num, 2));
function valueAtBit(num, bit) {
if(bit < 1) return
var numberString = num.toString(2).split("").reverse().join("")
//十进制转二进制-》数组-》反转-》字符串
return numberString[bit-1]
}
let num = 128
console.log(valueAtBit(num, 2));
function valueAtBit(num, bit) {
let str = num.toString(2);
return str.substr(-bit,1);
}
let num = 128
console.log(valueAtBit(num, 2));
6、二进制转换
描述:
将给定数字转换成二进制字符串。如果字符串长度不足 8 位,则在前面补 0 到满8位。
示例
输入:65
输出:01000001
function convertToBinary(num) {
let str = num.toString(2); // 将数字转换为二进制字符串
let len = 8 - str.length; // 计算需要补0的个数
// 使用for循环补0
for (let i = 0; i < len; i++) {
str = "0" + str;
}
return str;
}
let num = 65;
console.log(convertToBinary(num)); // 输出:01000001
function convertToBinary(num) {
return ('0'.repeat(8) + num.toString(2)).slice(-8);//从字符串末位向前截取8位
}
let num = 65;
console.log(convertToBinary(num)); // 输出:01000001
function convertToBinary(num) {
let str = num.toString(2);
let len = 8 - str.length;
return ('0'.repeat(len) + num.toString(2));
}
let num = 65;
console.log(convertToBinary(num));
function convertToBinary(num) {
let res=num.toString(2);
return res.length<8?new Array(8-res.length).fill(0).join('')+res:res;
//创建一个用0填充的数组变成字符串后与res拼接
}
let num = 65;
console.log(convertToBinary(num)); // 输出:01000001
function convertToBinary(num) {
var s = num.toString(2);
while(s.length<8){
s = "0"+s;
}
return s;
}
let num = 65;
console.log(convertToBinary(num)); // 输出:01000001
7、属性遍历
描述:
找出对象 obj 不在原型链上的属性(注意这题测试例子的冒号后面也有一个空格~)
1、返回数组,格式为 key: value
2、结果数组不要求顺序
示例
输入:var C = function() {this.foo = 'bar'; this.baz = 'bim';};
C.prototype.bop = 'bip';
iterate(new C());
输出:["foo: bar", "baz: bim"]
function iterate(obj) {
const result = [];
for (let key in obj) {//for in可以遍历到obj的原型属性和方法
// 使用 hasOwnProperty 检查属性是否是对象自身的属性,而不是从原型链继承的
if (obj.hasOwnProperty(key)) {
result.push(`${key}: ${obj[key]}`);
}
}
return result;
}
var C = function() {
this.foo = 'bar';
this.baz = 'bim';
};
C.prototype.bop = 'bip';
console.log(iterate(new C())); // 输出: ["foo: bar", "baz: bim"]
function iterate(obj) {
const keyArr = Object.keys(obj);
//Object.keys(obj) 只会遍历实例属性key值,不会遍历原型上的属性
const temp = []
for(let i in keyArr){
temp[i] = keyArr[i].concat(': ',obj[keyArr[i]])
}
return temp
}
var C = function() {
this.foo = 'bar';
this.baz = 'bim';
};
C.prototype.bop = 'bip';
console.log(iterate(new C())); // 输出: ["foo: bar", "baz: bim"]
function iterate(obj) {
return Object.keys(obj).map( k => `${k}: ${obj[k]}`)
}
var C = function() {
this.foo = 'bar';
this.baz = 'bim';
};
C.prototype.bop = 'bip';
console.log(iterate(new C())); // 输出: ["foo: bar", "baz: bim"]
8、 检查重复字符串
描述:给定字符串 str,检查其是否包含连续重复的字母(a-zA-Z),包含返回 true,否则返回 false
示例
输入:'rattler'
输出:true
function containsRepeatingLetter(str) {
for(let i=0;i<str.length-1;i++){//判断相邻字符是否相等,再判断是否为字母
if(str.charAt(i)==str.charAt(i+1)&& ((str.charAt(i)>='a'&&str.charAt(i)<='z')||(str.charAt(i)>='A'&&str.charAt(i)<='Z'))){
return true;
}
}
return false;
}
let str= 'rattler';
console.log(containsRepeatingLetter(str) );
function containsRepeatingLetter(str) {
return /([a-zA-Z])\1/.test(str)
}
let str= 'rarRRler';
console.log(containsRepeatingLetter(str) );
9、获取指定字符串
描述:
给定字符串 str,检查其是否包含 连续3个数字,请使用正则表达式实现。
1、如果包含,返回最先出现的 3 个数字的字符串
2、如果不包含,返回 false
示例
输入:'9876543'
输出:987
function captureThreeNumbers(str) {
debugger
var result = str.match(/(\d{3})/)
return result ? result[0] : false
}
let input = '987657777777743';
console.log(captureThreeNumbers(input)); // 输出: 987
10、 判断是否符合指定格式
描述:
给定字符串 str,检查其是否符合如下格式
1、XXX-XXX-XXXX
2、其中 X 为 Number 类型
示例
输入:'800-555-1212'
输出:true
function matchesPattern(str) {
let regs = /^\d{3}-\d{3}-\d{4}$/
return regs.test(str)
}
let str ='800-555-1212';
matchesPattern(str);
function matchesPattern(str) {
return (/^\d\d\d-\d\d\d-\d\d\d\d$/.test(str));
}
let str ='800-555-1212';
matchesPattern(str) ;
function matchesPattern(str) {
var reg=/^[0-9]{3}-[0-9]{3}-[0-9]{4}$/;
return reg.test(str);
}
let str ='800-555-1212'
matchesPattern(str)
三、中等
1、列表内容排序再渲染
描述:
场景描述:在一个 HTML 页面中,有一个无序列表(ul),其中包含了一些项目(li)。每个项目都有一个文本内容和一个唯一的 ID。你需要编写一个 JavaScript 函数来提取列表中所有项目的文本内容,并将它们按照 ID 进行排序,然后将排序后的文本内容重新渲染回去。
示例:
输入:
输出:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<ul id="myList">
<li id="item1">项目 1</li>
<li id="item3">项目 3</li>
<li id="item2">项目 2</li>
<li id="item4">项目 4</li>
</ul>
<script>
function sortAndReturnTextContent() {
debugger
const items = document.getElementById('myList').children
// 在此补全代码
document.getElementById('myList').innerHTML = Array.from(items)
.sort((a, b) => parseInt(a.id.slice(4)) - parseInt(b.id.slice(4)))
.map((item) => item.outerHTML)
.join('')
}
sortAndReturnTextContent()
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<ul id="myList">
<li id="item1">项目 1</li>
<li id="item3">项目 3</li>
<li id="item2">项目 2</li>
<li id="item4">项目 4</li>
</ul>
<script>
function sortAndReturnTextContent() {
debugger
const items = document.getElementById('myList').children;
const liArrays = [...items];
liArrays.sort((a, b) => {
return parseInt(a.id.slice(4)) - parseInt(b.id.slice(4));
});
for (let i of liArrays) {
document.getElementById("myList").appendChild(i);
//如果要附加的节点已经是某个元素的一个子节点,.appendChild()会先将该节点从其当前位置移除,然后再将其附加到指定元素的子节点列表的末尾。
}
}
sortAndReturnTextContent()
</script>
</body>
</html>
2、直角三角形
描述:
请补全JavaScript代码,要求在页面上渲染出一个直角三角形,三角形换行要求使用"br"实现。三角形如下:
*
**
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<div class='triangle'></div>
<script>
var triangle = document.querySelector('.triangle');
// 补全代码
let str = "";
for(let i=0;i<3;i++){
for(let j=0;j<i+1;j++){
str+="*";
}
str+="</br>";
}
triangle.innerHTML=str;
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<div class='triangle'>
*<br>**<br>***<br>
</div>
<script>
var triangle = document.querySelector('.triangle');
// 补全代码
var str='';
for(var i=1;i<=3;i++){
str+=`${'*'.repeat(i)}<br>`;
}
triangle.innerHTML=str;
</script>
</body>
</html>
3、文件扩展名
描述:请补全JavaScript代码,要求以字符串的形式返回文件名扩展名,文件名参数为"filename"。
const _getExFilename = (filename) => {
return "."+filename.split(".")[ filename.split(".").length-1]
}
console.log(_getExFilename("port.xml"))
const _getExFilename = (filename) => {
// 1.获取最后一个.的索引值
let index = filename.lastIndexOf(".");
// 2.截取.及其后面的内容
return filename.slice(0,index) && index !== -1 ? filename.slice(index) : '';
}
console.log(_getExFilename("port.xml"))
const _getExFilename = (filename) => {
let f = filename.indexOf('.')
return filename.slice(f,filename.length)
}
console.log(_getExFilename("port.xml"))
4、分隔符
描述:请补全JavaScript代码,要求返回参数数字的千分位分隔符字符串。
示例:
输入:_comma(12300)
输出:'12,300'
function _comma(number) {
let res = ''
let count = 0
const negative = number < 0 ? '-' : ''
number = Math.abs(number).toString()
for (let i = number.length - 1; i >= 0; i--) {
count += 1
res = number[i] + res
if (count % 3 === 0 && i !== 0 && number[i] !== '.') {
res = ',' + res
}
}
return negative + res
}
console.log(_comma(-123456789.89)) // -123,456,789.89
function _comma(number) {
let isnegative = number < 0;
number = Math.abs(number);
let numberStr = number.toString();
let result = numberStr.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
return isnegative ? "-" + result : result;
}
console.log(_comma(-123456789.89)) // -123,456,789.89
function _comma(number) {
debugger
// 补全代码
let isnegative = (number < 0)
console.log(isnegative);
number = Math.abs(number);
let numberStr = String(number);
let arr = numberStr.split("");
let length = arr.length;
let round = Math.floor(length / 3);
if (length % 3 === 0) round--;
while (round > 0) {
arr.splice((round) * (-3), 0, ",");
round--;
}
let result = arr.join("");
if (isnegative) result = '-' + result;
return (result);
}
console.log(_comma(-123456789.89)) // -123,456,789.89
5、单向绑定
描述:
请补全JavaScript代码,要求每当id为"input"的输入框值发生改变时触发id为"span"的标签内容同步改变。
注意:
- 必须使用DOM0级标准事件(onchange)
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
</head>
<body>
<input id="input" type="text" onchange="change(value)"/>
<span id="span"></span>
<script type="text/javascript">
// 补全代码
let content=document.querySelector("#span")
function change(val){
content.innerHTML=val
}
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
</head>
<body>
<input id="input" type="text" />
<span id="span"></span>
<script type="text/javascript">
document.getElementById("input").onchange = function(){
// dom事件里的函数的this指向触发者,即input标签
document.getElementById("span").innerHTML = this.value
}
</script>
</body>
</html>
6、创建数组
描述:
请补全JavaScript代码,要求返回一个长度为参数值并且每一项值都为参数值的数组。
注意:
- 请勿直接使用for/while
const _createArray = (number) => {
return Array(number).fill(number)
}
console.log(_createArray(4));
const _createArray = (number) => {
return Array.from({length: number}, () => number);
//Array.from函数接收两个参数,第一个参数为数组或对象,都表示返回数组的长度。当参数为数组时它确定了返回的新数组长度,当参数为对象时,需要添加“length”属性表明数组长度
//第二个参数为一个函数,即第一个数组参数中的每一项都调用该函数
}
console.log(_createArray(10));
const _createArray = (number) => {
const array = [...Array(number)].map((item)=>{
return number
})
return array
}
console.log(_createArray(4));
const _createArray = (number) => {
const list = new Array();
let newNumer = number
const fn = (list,newNumer) => {
if(newNumer > 0){
list.push(number);
newNumber = newNumer - 1 ;
fn(list,newNumber)
}
}
fn(list,newNumer)
return list
}
console.log(_createArray(4));
7、判断版本
描述:
请补全JavaScript代码,该函数接收两个参数分别为旧版本、新版本,当新版本高于旧版本时表明需要更新,返回true,否则返回false。
注意:
- 版本号格式均为"X.X.X"
- X属于[0,9]
- 当两个版本号相同时,不需要更新
const _shouldUpdate = (oldVersion, newVersion) => {
let oldversion = parseInt(oldVersion.split('.').join(''))
let newversion = parseInt(newVersion.split('.').join(''))
return newversion > oldversion
}
console.log( _shouldUpdate("1.4.1","1.4.9"))
const _shouldUpdate = (oldVersion, newVersion) => {
return oldVersion < newVersion;
//三个X都是1位数[0,9],可以直接比较字符串大小
}
console.log( _shouldUpdate("1.4.9","1.5.1"))
8、无重复数组
描述:
请补全JavaScript代码,实现一个函数,要求如下:
- 根据输入的数字范围[start,end]和随机数个数"n"生成随机数
- 生成的随机数存储到数组中,返回该数组
- 返回的数组不能有相同元素
注意: - 不需要考虑"n"大于数字范围的情况
示例
输入:getUniqueNums(2,10,4)
输出:[4,6,2,8]
const _getUniqueNums = (start,end,n) => {
let set = new Set()
while(set.size < n) {
set.add(Math.floor(Math.random() * (end - start + 1)+ start ))
}
return [...set]
}
console.log(_getUniqueNums(2,10,6))
const _getUniqueNums = (start,end,n) => {
var arr1 = []
var randomArr = []
for(var i = start ;i<=end;i++){
arr1.push(i)
}
debugger
while(randomArr.length<n){
var randomIndex = Math.floor(Math.random()*arr1.length)
randomArr.push(arr1[randomIndex])
arr1.splice(randomIndex,1)
}
return randomArr
}
console.log(_getUniqueNums(2,10,6))
9、数组排序
描述
请补全JavaScript代码,根据预设代码中的数组,实现以下功能:
- 列表只展示数组中的name属性
- 实现点击"销量升序"按钮,列表内容按照销量升序重新渲染
- 实现点击"销量降序"按钮,列表内容按照销量降序重新渲染
注意: - 必须使用DOM0级标准事件(onclick)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<button class='up'>销量升序</button>
<button class='down'>销量降序</button>
<ul></ul>
<script>
var cups = [
{ type: 1, price: 100, color: 'black', sales: 3000, name: '牛客logo马克杯' },
{ type: 2, price: 40, color: 'blue', sales: 1000, name: '无盖星空杯' },
{ type: 4, price: 60, color: 'green', sales: 200, name: '老式茶杯' },
{ type: 3, price: 50, color: 'green', sales: 600, name: '欧式印花杯' }
];
var ul = document.querySelector('ul');
var upbtn = document.querySelector('.up');
var downbtn = document.querySelector('.down');
// 渲染列表的函数
function renderList(cupsArray) {
ul.innerHTML = '';
cupsArray.forEach(cup => {
var li = document.createElement('li');
li.textContent = cup.name;
ul.appendChild(li);
});
}
// 升序排序函数
function sortAsc(cupsArray) {
return cupsArray.sort((a, b) => a.sales - b.sales);
}
// 降序排序函数
function sortDesc(cupsArray) {
return cupsArray.sort((a, b) => b.sales - a.sales);
}
// 绑定点击事件
upbtn.onclick = function() {
renderList(sortAsc([...cups])); // 使用解构赋值来避免直接修改原数组
};
downbtn.onclick = function() {
renderList(sortDesc([...cups]));
};
renderList(cups);
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<button class='up'>销量升序</button>
<button class='down'>销量降序</button>
<ul></ul>
<script>
var cups = [
{ type: 1, price: 100, color: 'black', sales: 3000, name: '牛客logo马克杯' },
{ type: 2, price: 40, color: 'blue', sales: 1000, name: '无盖星空杯' },
{ type: 4, price: 60, color: 'green', sales: 200, name: '老式茶杯' },
{ type: 3, price: 50, color: 'green', sales: 600, name: '欧式印花杯' }
]
var ul = document.querySelector('ul');
var upbtn = document.querySelector('.up');
var downbtn = document.querySelector('.down');
// 补全代码
upbtn.onclick = function(){
let newCups = [...cups];
newCups.sort((x,y)=>{
return x.sales-y.sales
});
rendList(newCups);
}
downbtn.onclick = function(){
let newCups = [...cups];
newCups.sort((x,y)=>{
return y.sales-x.sales
})
rendList(newCups);
}
function rendList(newCups){
let str ="";
newCups.map((x,y)=>{
str = str +"<li>"+x.name+"</li>";
})
ul.innerHTML = str;
}
</script>
</body>
</html>
10、新数组
描述:请补全JavaScript代码,该函数接受两个参数分别为数组、索引值,要求在不改变原数组的情况下返回删除了索引项的新数组。
const _delete = (array,index) => {
let newarray = array.concat()
newarray.splice(index,1);
return newarray;
}
console.log(_delete([1,2,4,6],2));
const _delete = (array,index) => {
let arrayNew = [...array];
arrayNew.splice(index,1);
return arrayNew;
}
console.log(_delete([1,2,4,6],2));
const _delete = (array,index) => {
return array.filter((n,i) => i!=index)
}
console.log(_delete([1,2,4,6],2))
const _delete = (array,index) => {
return array.slice(0,index).concat(array.slice(index+1))
}
console.log(_delete([1,2,4,6],2))
11、计数器
描述:
请补全JavaScript代码,要求每次调用函数"closure"时会返回一个新计数器。每当调用某个计数器时会返回一个数字且该数字会累加1。
注意:
- 初次调用返回值为1
- 每个计数器所统计的数字是独立的
function closure() {
// 存储计数器的值
let count = 0;
// 返回一个函数,该函数将作为计数器
return function() {
count += 1;
return count;
};
}
// 测试代码
let counter1 = closure(); // 创建一个新的计数器
let counter2 = closure(); // 创建另一个新的计数器
console.log(counter1()); // 输出: 1,初次调用返回值为1
console.log(counter1()); // 输出: 2,计数器1的值累加1
console.log(counter2()); // 输出: 1,初次调用返回值为1(与counter1独立)
console.log(counter1()); // 输出: 3,计数器1的值继续累加1
console.log(counter2()); // 输出: 2,计数器2的值累加1
12、列表动态渲染
描述:
请补全JavaScript代码,将预设代码中的"people"数组渲染在页面中。实现下面的列表:
- 牛油1号 20岁
- 牛油2号 21岁
- 牛油3号 19岁
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<ul></ul>
<script>
var people = [
{ name: '牛油1号', id: 1, age: 20 },
{ name: '牛油2号', id: 2, age: 21 },
{ name: '牛油3号', id: 3, age: 19 },
]
var ul = document.querySelector('ul');
// 补全代码
let str = "";
people.map(x=>{
str += `<li>${x.name} ${x.age}</li>`
})
ul.innerHTML = str
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<ul></ul>
<script>
var people = [
{ name: '牛油1号', id: 1, age: 20 },
{ name: '牛油2号', id: 2, age: 21 },
{ name: '牛油3号', id: 3, age: 19 },
]
var ul = document.querySelector('ul');
// 补全代码
let str = "";
for (const item of people) {
str += `<li>${item.name} ${item.age}</li>`
}
ul.innerHTML = str;
</script>
</body>
</html>
13、模板字符串
描述:
请补全JavaScript代码,实现以下功能:
- 根据已有的person对象的注册时间求出距离当前时间的天数(天数向下取整)。
- 将获得的天数和person数据拼接成字符串,作为h2标签的内容。
注意:使用模板字符串进行字符串拼接,字符串最终内容如:尊贵的牛客网2级用户小丽您好,您已经注册牛客网3天啦~
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<h2></h2>
<script>
var person = {
level: '2',
name: '小丽',
registTime: '2021-11-01',
}
var h2 = document.querySelector('h2');
// 补全代码
let str = "";
// 输入日期字符串
const inputDateString =person.registTime;
const inputDate = new Date(inputDateString);
const currentDate = new Date();
const timeDifference = currentDate - inputDate;
const daysDifference = Math.floor(timeDifference / (1000 * 60 * 60 * 24));
h2.innerHTML = `尊贵的牛客网${person.level}级用户小丽您好,您已经注册牛客网${daysDifference}天啦~`
</script>
</body>
</html>
14、类继承
描述:
请补全JavaScript代码,完成类的继承。要求如下:
- "Chinese"类继承于"Human"类
- "Human"类实现一个函数"getName",返回该实例的"name"属性
- "Chinese"类构造函数有两个参数,分别为"name"、"age"
- "Chinese"类实现一个函数"getAge",返回该实例的"age"属性
class Human {
constructor(name) {
this.name = name;
this.kingdom = 'animal';
this.color = ['yellow', 'white', 'brown', 'black'];
}
// 实现 getName 方法,返回实例的 name 属性
getName() {
return this.name;
}
}
// Chinese 类继承自 Human 类
class Chinese extends Human {
constructor(name, age) {
// 调用父类的构造函数,传入 name 参数
super(name);
this.age = age;
}
// 实现 getAge 方法,返回实例的 age 属性
getAge() {
return this.age;
}
}
// 示例用法
const chinesePerson = new Chinese('张三', 30);
console.log(chinesePerson.getName()); // 输出: 张三
console.log(chinesePerson.getAge()); // 输出: 30
15、参数解析器
描述:
请补全JavaScript代码,要求将字符串参数URL中的参数解析并以对象的形式返回。
示例
输入:getParams('nowcoder.com/online?id=1…')
输出:{id:1, salas: 100}
function _getParams(url) {
let splitUrl = url.slice(url.lastIndexOf('?')+1).split('&')
let obj = {}
splitUrl.map(n => {
let [key,value] = n.split('=')
obj[key] = value
})
console.log(obj)
return obj
}
getParams('https://nowcoder.com/online?id=1&salas=1000')
function _getParams(url) {
var searchString = url.substring(url.indexOf('?'));//截取字符串
const params = new URLSearchParams(searchString);//通过URLSearchParams方法变成深度数组
const obj = Object.fromEntries(params)//通过fromEntries转变成对象
console.log(obj)
return obj
}
getParams('https://nowcoder.com/online?id=1&salas=1000')
const getParams = (url) => {
let arr = url.match(/(\w+)=(\w+)/gi);//匹配 (\w+)=(\w+) 的子字符串
let obj = {};
arr.map(item => {
let [key, value] = item.split("=");
obj[key] = value;
})
return obj;
}
getParams('https://nowcoder.com/online?id=1&salas=1000')
const getParams = (url) => {
let params= url.split("?")[1].split("&");
let obj = {};
params.map(x=>{
let param = x.split("=");
obj[param[0]]=param[1];
})
return obj;
}
getParams('https://nowcoder.com/online?id=1&salas=1000')
16、生成页码
描述:
请补全JavaScript代码,要求根据参数动态生成"li"标签页码并插入"ul"标签下。要求如下:
- "allItem"为总数据项个数,"pageItem"为每页的数据项个数
- "li"标签内容为当前页码数,页码从1开始
示例
输入:_createPage(13,2)
输出:"li"长度为7,"li"内容依次为"1","2","3","4","5","6","7"
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
</head>
<body>
<ul id="ul">
</ul>
<script type="text/javascript">
const _createPage = (allItem, pageItem) => {
debugger
let page = Math.ceil(allItem/pageItem);//向上取整
let str = "";
for (let i=1;i<=page;i++){
str += `<li>${i}</li>`;
}
document.getElementById("id").innerHTML = str;
}
console.log(_createPage(13,2));
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
</head>
<body>
<ul id="ul">
</ul>
<script type="text/javascript">
const _createPage = (allItem, pageItem) => {
let ul = document.querySelector('#ul')
let pageNumber = Math.ceil(allItem / pageItem)
for(let i=1 ; i<=pageNumber ; i++) {
let li = document.createElement('li')
li.innerText = i
ul.appendChild(li)
}
}
console.log(_createPage(13,2));
</script>
</body>
</html>
17、总成绩排名
描述:请补全JavaScript代码,要求将数组参数中的对象以总成绩(包括性"chinese"、"math"、"english")从高到低进行排序并返回。
let arr =[
{id:"001",chinese:112,math:139,english:103},
{id:"002",chinese:132,math:129,english:113},
{id:"003",chinese:122,math:119,english:123},
{id:"004",chinese:102,math:109,english:133}
]
const _rank = array => {
// 补全代码
array.map(x=>{
return x.total = x.chinese+x.math+x.english;
})
array.sort((a,b)=>{
return b.total-a.total
})
return array
}
console.log( _rank(arr));
let arr =[ {id:"001",chinese:112,math:139,english:103}, {id:"002",chinese:132,math:129,english:113}, {id:"003",chinese:122,math:119,english:123}, {id:"004",chinese:102,math:109,english:133} ]
const _rank = array => {
return array.sort((a,b)=>(b.chinese+b.math+b.english) - (a.chinese+a.math+a.english))
}
console.log( _rank(arr));
18、子字符串频次
描述:请补全JavaScript代码,该函数接受两个参数分别为字符串、子字符串,要求返回子字符串在字符串中出现的频次。
const _searchStrIndexOf = (str, target) => {
return str.split(target).length - 1
}
console.log( _searchStrIndexOf("3rekoreuurere44uu444","uu"));
const _searchStrIndexOf = (str, target) => {
let reg=new RegExp(target,'g');
return str.match(reg).length;
//使用正则表达来计算共有几个target,match会返回符合条件的数组
}
console.log( _searchStrIndexOf("3rekoreuurere44uu444","uu"));
const _searchStrIndexOf = (str, target) => {
let index = str.indexOf(target)
let sum = 0
while (index > -1) {
//在每次循环中,上一个找到的位置的下一个字符开始搜索
index = str.indexOf(target, index + 1);
sum++
}
return sum
}
console.log( _searchStrIndexOf("3rekoreuurere44uu444","uu"));
const _searchStrIndexOf = (str, target) => {
let n = target.length;
let l = str.length;
let result = 0, i = 0;
debugger
while (i < l - n) { // 修改循环条件
let tmp = str.substr(i, n);
if (tmp === target) {
result++;
}
i++;
}
return result;
}
console.log( _searchStrIndexOf("3rekoreuurere44uu444","uu"));
19、继承
描述:
请补全JavaScript代码,实现以下功能:
- 给"Human"构造函数的原型对象添加"getName"方法,返回当前实例"name"属性
- 将"Chinese"构造函数继承于"Human"构造函数
- 给"Chinese"构造函数的原型对象添加"getAge"方法,返回当前实例"age"属性
function Human(name) {
this.name = name
this.kingdom = 'animal'
this.color = ['yellow', 'white', 'brown', 'black']
}
//补全的位置开始:
Human.prototype.getName = function(){
return this.name;
};
//补全的位置结束
function Chinese(name,age) {
Human.call(this,name)
this.age = age
this.color = 'yellow'
}
//补全的位置开始:
Chinese.prototype = new Human();
Chinese.prototype.constructor = Chinese;
Chinese.prototype.getAge = function(){
return this.age;
}
//补全的位置结束
20、判断斐波那契数组
描述:
请补全JavaScript代码,要求以Boolean的形式返回参数数组是否为斐波那契数列。在数学上,斐波那契数列以如下方法定义:F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N)
注意:
- [0,1,1]为最短有效斐波那契数列
const _isFibonacci = array => {
if(array.length<3){
return false;
}
let flag = true;
for(let i=array.lenng-1;i>=2;i--){
if(!(array[i]= array[i-1]+array[i-2])){
flag = false;
return false
}
}
return flag
}
console.log(_isFibonacci([0,1,1,2,3,5]))
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
}
console.log(_isFibonacci([0,1,1,2,3,5]))
const _isFibonacci = (array) => {
// 判断长度是否合格
if (array.length < 3) return false;
// 当index索引值小于3时判断是否为最短且有效的斐波那契数列
// 当index索引值大于3时判断当前item值是否为前两项索引item项值的和
return array.every((item, index) =>
index < 3
? array[0] === 0 && array[1] === 1 && array[2] === 1
: item === array[index - 1] + array[index - 2]
);
};
console.log(_isFibonacci([0,1,1,2,3,5]))