打印出 1 - 10000 之间的所有对称数
//所谓对称数就是指从左到右遍历与从右到左遍历的结果一样,如121,不能是个位数
function duiCheng()(
Arrar(10000).keys().filter(index)=>{ //创建10000个元素的数组,keys就是0~9999的数组
return index.toString().length > 1 && //排除个位数
index.toString().split('').reverse().join('') == index
})
)
周一算法题之「移动零」
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非
零元素的相对顺序。如输入: [0,1,0,3,12] 输出: [1,3,12,0,0]复制代码说明: 必须
在原数组上操作,不能拷贝额外的数组。 尽量减少操作次数
function moveZero(arr){
var len = arr.length //保存数组长度,每次将0移到最后,len减1,减少循环
for(var i=0;i<len;i++){
if(!arr[i]){
arr.push(arr.splice(i,1)) //删除该元素,也就是0,放到数组末尾
i-- //删除后i要减1才不会跳过下一个元素
len-- //每次移动后,len减1,减少循环,末尾的0不需要遍历
}
}
return arr
}
var、let 和 const 区别的实现原理是什么
var 和 let 用以声明变量,const 用于声明只读的常量;
var 声明的变量,不存在块级作用域,在全局范围内都有效,
let 和 const声明的,只在它所在的代码块内有效;
let 和 const 不存在像 var 那样的 “变量提升” 现象,所以 var 定义变
量可以先使用,后声明,而 let 和 const 只可先声明,后使用;
let 声明的变量存在暂时性死区,即只要块级作用域中存在 let,那么它
所声明的变量就绑定了这个区域,不再受外部的影响。
let 不允许在相同作用域内,重复声明同一个变量;
const 在声明时必须初始化赋值,一旦声明,其声明的值就不允许改变,
更不允许重复声明;如 const 声明了一个复合类型的常量,其存储的是一个引
用地址,不允许改变的是这个地址,而对象本身是可变的。**
变量与内存之间的关系,主要由三个部分组成:变量名 内存地址 内存空间**
JS 引擎在读取变量时,先找到变量绑定的内存地址,然后找到地址所指向的内
存空间,最后读取其中的内容。当变量改变时,JS 引擎不会用新值覆盖之前旧
值的内存空间(虽然从写代码的角度来看,确实像是被覆盖掉了),而是重新
分配一个新的内存空间来存储新值,并将新的内存地址与变量进行绑定,JS 引
擎会在合适的时机进行 GC,回收旧的内存空间。const 定义变量(常量)后,
变量名与内存地址之间建立了一种不可变的绑定关系,阻隔变量地址被改变,
当 const 定义的变量进行重新赋值时,根据前面的论述,JS 引擎会尝试重新分
配新的内存空间,所以会被拒绝,便会抛出异常。
请实现一个 add 函数,满足以下功能
add(1); // 1
add(1)(2); // 3
add(1)(2)(3);// 6
add(1)(2, 3); // 6
add(1, 2)(3); // 6
add(1, 2, 3); // 6
//要加工的函数:const add = (...args) => args.reduce((a, b) => a + b);
//分析:柯里化操作(闭包收集参数),根据参数达没达到总的参数个数决定是收集还是调用
//实现方法1:数组收集参数
function curry(fn,length){ //fn=add函数,length=3
var argArr = [] //收集参数
return function result(...args){ //返回一个函数
if(args.length+argArr.length>=length){ //如果参数收集完毕就执行
return fn(...argArr,...args) //执行函数
}
else{ //参数数量不够,小于3 如:add(1,2)
argArr.push(...args) //收集参数
return result //递归收集(3)
}
}
}
//实现方法2:利用bind具备收集参数的机制来实现参数收集
//bind源码:
Function.prototype.bind = function (context) {
var self = this; //调用的函数
// 第 1 个参数是指定的 this,截取保存第 1 个之后的参数
var args = Array.prototype.slice.call(arguments, 1); //(this,1,2)
return function () { //返回一个新函数
// 此时的 arguments 是指 bind 返回的函数调用时接收的参数,(3):arguments就是3
// 类数组转成数组
var bindArgs = Array.prototype.slice.call(arguments);
//绑定this到context,这里参数是concat,就变成了[1,2,3]
return self.apply( context, args.concat(bindArgs) );
}
}
function curry(fn,length){ //fn=add函数,length初始为空,代表剩余参数个数
length = length || fn.length //length初始化为总的参数个数3
return function(...args){ //返回一个函数
if(args.length>=length){ //如果参数收集完毕就执行
//fn经过bind之后把之前的参数已经收集,这里不需要cancat
return fn.apply(this,args) //执行函数
}
else{ //参数数量不够,小于3 如:add(1,2)
//bind过的函数会收集参数
curry(fn.bind(this,...args),length-args.length) //递归调用,传递剩余参数个数
}
}
}
//实现方法3 直观写法,不返回
function curry = fn => judge = (...args)=>{ 包装fn函数为judge函数
if(args.length > fn.length){ //如果参数收集完毕就执行
return fn(...args) //注意这里不需要return
}
else (...arg)=>judge(...args,arg) //多阶函数,收集参数递归调用
}
react-router 里的link标签和a标签有什么区别
如何禁掉 标签默认事件,禁掉之后如何实现跳转。
Link 做了 3 件事情:
1.有 onclick 那就执行 onclick: if (_this.props.onClick) _this.props.onClick(event);
2.click 的时候阻止 a 标签默认事件(这样子点击就不会跳转和刷面:
event.preventDefault();
3.再取得跳转 href(即是 to),用 history(前端路由两种方式之一,history
& hash)跳转,此时只是链接变了,并没有刷新页面
周一算法题之「两数之和」
给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。你可以假设每个输入
只对应一种答案,且同样的元素不能被重复利用。
示例:给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
function answer(arr,target){ //target代表目标值9
var map = {} //用map保存遍历的数以及下表,我们只需要在剩余项中去找target-当前值
for(var i=0;i<arr.length;i++){
if(map[target-arr[i]]){ //遍历到7时,发现map[2]存在,直接返回结果即可
return [map[target-arr[i]],i]
}
else{
map[arr[i]] = i //保存{2:0}到map中
}
}
}
在输入框中如何判断输入的是一个正确的网址。
function isUrl(url){
const a = document.createElement('a') //创建a标签
a.href= url
return [
/^(http|https):$/.test(a.protocol), //必须是http或者https协议
a.host, //必须要有主机名
a.pathName!=url,
a.pathName!=`/${url}`
].find(x=>!x) == undefined //去找不满足条件的,发现找不到,即全部满足证明url有效
}
实现 convert 方法,把原始 list 转换成树形结构,要求尽可能降低时间复杂度
以下数据结构中,id 代表部门编号,name 是部门名称,parentId 是父部门编号,为 0 代表
一级部门,现在要求实现一个 convert 方法,把原始 list 转换成树形结构,parentId 为多少
挂载在该 id 的属性 children 数组下,结构如下:
// 原始 list 如下 let list =[
{id:1,name:'部门 A',parentId:0},
{id:2,name:'部门 B',parentId:0},
{id:3,name:'部门 C',parentId:1},
{id:4,name:'部门 D',parentId:1},
{id:5,name:'部门 E',parentId:2},
{id:6,name:'部门 F',parentId:3},
{id:7,name:'部门 G',parentId:2},
{id:8,name:'部门 H',parentId:4}
];
const result = convert(list, ...);
// 转换后的结果如下 let result = [
{ id: 1, name: '部门 A', parentId: 0, children: [
{ id: 3, name: '部门 C', parentId: 1, children: [
{ id: 6, name: '部门 F', parentId: 3 },
{id: 16, name: '部门 L', parentId: 3 }
]
},
{ id: 4, name: '部门 D', parentId: 1, children: [
{ id: 8, name: '部门 H', parentId: 4 }
]
}
]
},
···
];
实现代码:
function convert(list){
var res = []
var map = list.forEach(item=>map[item.id] = item) //构造map,key是id,value是整个对象
for(var i=0;i<list.length;i++){
var item = list[i]
if(!item.parentId) {
res.push(item) //最上层的
continue;
}r
if(map[item.parentId]){ //如果有父亲,就放入父亲的children中
var parent = map[item.parentId]
parent.children = parent.children||[]
parent.children.push(item)
}
}
return res
}
设计并实现 Peromise.race()
//参数全部都是promse的情况
Promise.prototype.race = function(promises){
new Promise((resolve,reject)=>{
promises.forEach(promise=>promise.then(resolve,reject)) //谁先执行完成谁就先返回
})
}
//参数实现了iterator接口的情况
Promise._myrace = function(iterator){ //实现了iterator接口的集合
return new Promise((resolve,reject)=>{
try{
let it = iterator[Symbol.iterator]() //获取迭代器对象
while(true){ //死循环,只要有一个执行完毕就结束循环
let res = it.next() //获取每一项
if(res.done) break //如果执行完毕
if(res.value instanceof Promise) //如果本身就是promise
res.value.then(resolve,reject)
else
resolve(res.value) //done会置为true
}
}
catch(err){
reject(err)
}
})
}
实现模糊搜索结果的关键词高亮显示
//v-html绑定计算属性,只要输入框输入内容变化就会替换v-html
<template lang="">
<span v-html="ruleTitle" ></span>
</template>
<script>
export default {
props: {
item: '',
searchVal: '',
},
computed: {
ruleTitle() {
let titleString = this.item;
if (!titleString) {
return '未知';
}
if (this.searchVal && this.searchVal.length > 0) {
// 匹配关键字正则
const replaceReg = new RegExp(this.searchVal, 'g');
// 高亮替换v-html值
const replaceString = `<span class="red">${this.searchVal}</span>`;
// 开始替换
titleString = titleString.replace(replaceReg, replaceString);
}
return titleString;
},
},
};
</script>
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!