2021-06-24
1、// 用js 实现一个无限极累加的函数, 形如:
add(1) //=> 1;
add(1)(2) //=> 2;
add(1)(2)(3) //=> 6;
add(1)(2)(3)(4) //=> 10;
以此类推
function add(a) {
function temp(b) {
a+=b;
return temp;
}
temp.toString = function() {
return a;
}
return temp;
}
console.log(add(1)(2)(3)); // f 6
2、// 实现 add(1,2,3) == 6, add(1,2,3)() = 6, add(1)(2)(3) = 6, add(1)(2)(3)() = 6
function add () {
console.log(arguments);
console.log([...arguments]);
let res = [...arguments].reduce((a, b)=>{
return a+b;
}, 0);
let temp=function() { // 使用闭包
if(arguments.length){
res+=[...arguments].reduce((a, b)=>{
return a+b;
}, 0); // 累加
return temp;
} else {
return res;
}
}
temp.toString = function() { // 重写toSting() 方法
return res;
}
return temp; // 返回一个函数
}
console.log(add(1,2,3)()) //6
console.log(add(1,2,3)) //f 6
console.log(add(1)(3)) // f 4
console.log(add(1)(3)(5)()) //9
https://blog.csdn.net/PHPxiaoxuesheng/article/details/105286190
3、函数参数不定长
function add(...args) {
return args.reduce((a,b) => a+b);
}
function curry(fn) {
const res = [];
let args = [];
return function _c(...newArgs) {
if(newArgs.length){
args = [...args, ...newArgs];
return _c;
} else {
return fn.apply(this, args);
}
}
}
let addCurry = curry(add)
addCurry(1)(2,3)(4)();
4、过滤树形数据,把符合条件的数据过滤出来,树形数据如下:
const objarr= [{
"id": 1,
"isshow": true,
"children": [{
"id": 2,
"isshow": true,
"children": [{
"id": 100268,
"isshow": false,
"showname": "ccccc"
}, {
"id": 6,
"isshow": true,
"showname": "纯纯粹粹"
}, {
"id": 100500,
"isshow": true,
"showname": "666"
}],
"showname": "1.1猜猜猜等到"
}],
"showname": "嗯哼"
}, {
"id": 3,
"isshow": true,
"children": [{
"id": 4,
"isshow": true,
"showname": "2.1"
}, {
"id": 5,
"isshow": true,
"showname": "纯纯粹粹纯纯粹粹"
}],
"showname": "2"
}, {
"id": 100121,
"isshow": true,
"children": [{
"id": 100122,
"isshow": true,
"showname": "vvv v"
}],
"showname": "单位名称"
}]
function convert(arr) {
const newArr = arr.filter(item => item.isshow);
// console.log(newArr);
return newArr.map(item => {
if (item.children) {
item.children = convert(item.children);
}
return item;
})
}
const arr = convert(objarr);
console.log(arr);
// 菜单列表
const menuList = [{
name: '系统管理',
code: 'system_manage',
children: [{
name: '用户管理',
code: 'user_manage',
children: [{
name: '添加用户',
code: 'add_user'
}, {
name: '编辑用户',
code: 'edit_user'
}, {
name: '删除用户',
code: 'del_user'
}]
}, {
name: '角色管理',
code: 'role_manage',
children: [{
name: '添加角色',
code: 'add_role'
}]
}]
}, {
name: '业务管理',
code: 'bus_manage',
children: [{
name: '流程管理',
code: 'process_manage'
}]
}, {
name: '订单管理',
code: 'order_manage'
}]
// 权限列表
const myMenuCode = ['system_manage', 'user_manage', 'add_user', 'order_manage']
const filterMenu = (menuList, menuCode) => {
return menuList.filter(item => {
return menuCode.indexOf(item.code) > -1
}).map(item => {
item = Object.assign({}, item)
if (item.children) {
item.children = filterMenu(item.children, menuCode)
}
return item
})
}
// 过滤后的菜单
const myMenu = filterMenu(menuList, myMenuCode)
console.log(myMenu)
3、js常见的安全漏洞问题及解决方案
4、require和import的区别
https://zhuanlan.zhihu.com/p/121770261
1)require是运行时调用,所以可以随处引入
import是编译时调用,必须放在文件开头引入,目前部分浏览器不支持,需要用
babel把es6转成es5再执行。
2)
import(es6语法)
主要有俩个功能:export和import
export用于对外输出本模块(一个文件可以理解为一个模块)变量的接口
import用于在一个模块中加载export输出变量的接口。
require(CommandJS规范 ,在nodejs中使用)
在nodejs环境中,我们采用的是CommandJS模块规范,使用require引入模块, 使用module.exports导出接口
5 、实现把一个字符串的大写转成小写、小写转为大写
0 ~ 9 (Unicode编码值范围:48~57)
a ~ z(Unicode编码值范围:97~122)
A ~ Z(Unicode编码值范围:[65~90])
// js 将字符串反转
function strReverse(str) {
var tmp = str.split('');
return (tmp.reverse()).join('');
}
console.log(strReverse('abcdef'))
// js 将字符串中的大写变成小写,小写变成大写
function strChange(arg) {
var str=arg.split('');
for(var i = 0; i < str.length; i++) {
if (str[i].charCodeAt() >= 65 && str[i].charCodeAt() <= 90) {
str[i] = str[i].toLowerCase();
} else {
str[i] = str[i].toUpperCase();
}
}
return str.join('');
}
console.log(strChange('abcERdsQ2d'))
var str = '123adaAWEEER';
Array.prototype.map.call(str,a=>a.toUpperCase(a)==a?a.toLowerCase():a.toUpperCase()).join('');
【代码分析:】
利用数组的map方法将字符串变成字符数组循环操作,最后将大小写互换后的字符数组再拼接成字符串。
互换逻辑:按字符转换,先转成大写与原字符比较如果相等说明它是大写,则调用转换为小写的方法,否则调用转换为大写的方法。
6、 Set Map weakMap weakSet的区别以及map和普通的对象有什么区别?
https://blog.csdn.net/qq_30101131/article/details/88544297
https://blog.csdn.net/weixin_40073115/article/details/104014232
https://www.cnblogs.com/magicg/p/13131383.html
set
set定义及特征
- 在js中Set 对象允许存储任何类型的唯一值,无论是原始值或者是对象引用。
- 顶层数据结构不具备key—>value特征,内部会自动加index序列。
- 可以存储不同类型的任何数据。
set方法
size属性: 返回集合的元素个数。(类似数组的长度length)
add(value)方法: 向集合中添加一个元素value。注意:如果向集合中添加一个已经存在的元素,不报错但是集合不会改变。
delete(value)方法: 从集合中删除元素value。
has(value)方法: 判断value是否在集合中,返回true或false.
clear()方法: 清空集合。
set应用场景
鉴于set存储值的不重复特性,经常被用来求数组去重,交集,并集,差集等操作。
1、数组去重
let arry = [1, 2, 3, 4, 4,1,2,3,2];
var mySet = new Set(arry);
let newArry = [...mySet]; // [1, 2, 3, 4]
2、求并集,交集,差集。
//set求并集
let arryA= [2,3,4,5,6],arryB = [3,4,5,6,7,8];
let setAB = new Set([...arryA,...arryB]);
let newArryAB = [...setAB];
console.log(newArryAB); //[2,3,4,5,6,7,8]
//求交集
let arryC= [2,3,4,5,6],arryD = [3,4,5,6,7,8];
let setC = new Set(arryC);
let setD = new Set(arryD);
let newArryC_D = arryA.filter(x=>setD.has(x));
console.log(newArryC_D); //[3,4,5,6]
//求差集
let newArryD_C = arryA.filter(x=>!setD.has(x));
let newArryD_D = arryB.filter(x=>!setC.has(x));
let newArryCD = [...newArryD_C,...newArryD_D];
console.log(newArryCD); //[2,7,8]
map
map定义及特征
Map 对象保存键值对。任何值(对象或者原始值) 都可以作为一个键或一个值。
Map常用属性及增删改查方法:
size: 属性,取出字典的长度
set(key, value):方法,向字典中添加新元素
get(key):方法,通过键查找特定的数值并返回
has(key):方法,判断字典中是否存在键key
delete(key):方法,通过键 key 从字典中移除对应的数据
clear():方法,将这个字典中的所有元素删除
Map 和 Object 的区别
(https://www.cnblogs.com/ysx215/p/11387938.html)
####### 1、Key filed
在 Object 中, key 必须是简单数据类型(整数,字符串或者是 symbol),而在 Map 中则可以是 JavaScript 支持的所有数据类型,也就是说可以用一个 Object 来当做一个Map元素的 key。
####### 2、元素顺序
Map 元素的顺序遵循插入的顺序,而 Object 的则没有这一特性。
####### 3、继承
Map 继承自 Object 对象。
map的遍历
for … of
forEach
for(let [key,value] of map){
console.log("key:"+JSON.stringify(key)+"-------value:"+JSON.stringify(value))
}
map.forEach((value,key)=>{
console.log("key:"+JSON.stringify(key)+"-------value:"+JSON.stringify(value))
})
map与数组之间的转换
let arryK = [[1,2],[3,4],[5,6]];
let mapK = new Map(arryK);
let mapP = Array.from(mapK);
console.log(mapK);
console.log(mapP);
WeakSet
和Set结构类似,也是不重复的值的集合,但WeakSet的成员只能是对象。
WeakSet的API:add() //增 ;delete() //删; has() //是否存在
注意:ws没有size属性,不可遍历。因为WeakSet的成员都是弱引用,随时可能消失,成员是不稳定的。
WeakSet的用处:
(1)使用ws储存DOM节点,就不用担心节点从文档移除时,会引发内存泄漏(即在被移除的节点上绑定的click等事件)。
(2)下面代码保证了Foo的实例方法,只能在Foo的实例上调用。这里使用 WeakSet 的好处是,foos对实例的引用,不会被计入内存回收机制,所以删除实例的时候,不用考虑foos,也不会出现内存泄漏。
WeakMap与Map的区别:
WeakMap 对象是一组键值对的集合,其中的键是弱引用对象,而值可以是任意。
注意,WeakMap 弱引用的只是键名,而不是键值。键值依然是正常引用。
WeakMap 中,每个键对自己所引用对象的引用都是弱引用,在没有其他引用和该键引用同一对象,这个对象将会被垃圾回收(相应的key则变成无效的),所以,WeakMap 的 key 是不可枚举的。
用WeakMap来实现私有属性
7、http中简单请求和复杂请求的区别
setTimeout、setInterval的区别
setTimeout() 只执行 code 一次。如果要多次调用,请使用 setInterval() 或者让 code 自身再次调用 setTimeout()。
方法一 es6块级作用域let
function count(){
for (let i=0; i<5; i++) {
setTimeout(() => console.log(i), 1000*i)
}
}
count() // 0 1 2 3 4
// 函数表达式的写法和上面写法效果一样
function count(){
for (let i=0; i<5; i++) {
(function(){
setTimeout(() => console.log(i), 1000*i)
})()
}
}
count()
方法二 es5写法:自执行函数
function count(){
for (var i=0; i<5; i++) {
(function(i){
setTimeout(() => console.log(i), 1000*i)
})(i)
}
}
count()
for(var i = 0;i<10;i++){
setTimeout(function(){
console.log(i)
},100)
} // 输出全是10( 10个10)
// 输出全是10的原因是因为i是全局变量,最后访问的都是全局变量i,而每次循环改变i的值就是改变全局变量的值,故而输出值均为10
// 之前对于这种问题的解决办法是通过闭包来实现
for(let i = 0;i<10;i++){
setTimeout(function(){
console.log(i)
},100)
} // 输出0123456789;
8、实现一个执行多次的有间隔的定时器函数
const repeatFunc = repeat(console.log, 4, 3000)
repeatFunc("helloworld")//会输出四次helloworld,每次间隔3s
//方法一 利用setInterval
function repeat (func, times, wait) {
return function(content){
var count = 0;
var interval = setInterval(function(){
count += 1;
func(content);
if(count === times){
clearInterval(interval);
}
}, wait);
}
}
const repeatFunc = repeat(alert, 4, 3000)
repeatFunc("hellworld");
// 方法二
function repeat(func, count, wait) {
return async function(...arg){
for(let i=0;i<count;i++){
await new Promise(function(resolve,reject){
setTimeout(() => {
func.apply(this,arg)
resolve()
}, wait);
})
}
}
}
const repeatFunc = repeat(console.log, 4, 3000)
repeatFunc("helloworld")