一、求一个字符串出现的次数
function queryStr(str){
let json = {};
let max = 0;
let msg = "";
for(let i = 0;i<str.length;i++){
if(!json[str.charAt(i)]) {
json[str.charAt(i)] = 1;
} else {
json[str.charAt(i)]++;
}
}
// 循环json对象
for(let i in json) {
if(json[i]>max){
max = json[i];
msg = i;
}
}
return {
max,msg
}
}
console.log(
"出现字数最多的字符是:",
queryStr("hello").msg,
"出现次数为:"
queryStr("hello").max
)
二、判断一个对象是否为数组
- 使用Array.isArray判断,如果返回true,说明是数组
- 使用instanceof Array判断,如果返回true,说明是数组
- 使用Object.prototype.toString.call()判断
function isArray(arg) {
if(typeof arg === "object") {
return Object.prototype.toString.call(arg) === "[Object Array]"
}
return false
}
Object对象和它的原型链上各自有一个toString()方法,第一个返回的是一个函数,第二个返回的是值类型。
通过call将Array的this上下文切换到Object,从而调用了Object.prototype.toString(),因此返回[object Array]
三、监听函数
function on(elem,type,selector,fn) {
if(fn == null) {
fn = selector;
selector = null
}
elem.addEventListener(type,function(e){
const target = e.target;
if(selector){
if(target.matches(selector)) {
fn.call(target.e);
}
} else {
fn(e)
}
})
}
四、手写简易的ajax
function ajax(url) {
const p = newPromise((resolve,reject) => {
const xhr = new XMLHttpRequest();
xhr.open("GET",url);
xhr.onreadystatechange=function(){
if(xhr.readyState === 4) {
if(xhr.status=== 200) {
resolve(JSON.parse(xhr.responseText));
} else if(xhr.status === 400) {
reject(new Error("404 not found"));
}
}
}
xhr.send(null)
})
return p;
}
const url="/data/test.json";
ajax(url).then((res) => console.log(res))
.catch((err)=>console.error(err));
五、节流防抖
函数防抖
在事件被触发n秒后再执行回调,如果在这n秒内有被触发,则重新计时
没有防抖的input
function ajax(content) {
console.log('ajax request' + content)
}
let inputa = document.getElementById('unDebounce')
inputa.addEventListener('keyup',function(e){
ajax(e.target.value)
})
加入防抖后的input
function ajax(content) {
console.log('ajax request' + content)
}
function debounce(fun,delay){
return function(args) {
let that = this;
let _args = args;
clearTimeout(fun.id)
fun.id = setTimeout(function() {
fun.call(that,_args)
},delay)
}
}
let inputb = document.getElementById('debounce')
let debounceAjax = debounce(ajax,500)
inputb.addEventListener('keyup',function(e) {
debounceAjax(e.target.value)
})
函数节流
规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效
function throttle(fun,delay) {
let last,deferTimer;
return function(args) {
let that = this;
let _args = arguments;
let now = +new Date()
if(last && now<last + delay) {
clearTimeout(deferTimer)
deferTimer = setTimeout(function() {
last = now;
fun.apply(that,_args)
},delay)
} else {
last = now
fun.apply(that,_args)
}
}
}
let throttleAjax = throttle(ajax,1000)
let inputc = document.getElementById('throttle')
inputc.addEventListener('keyup', function(e){
throttleAjax(e.target.value)
})
在不断输入时,ajax会按照我们设定的时间,每1s执行一次 结合应用场景
debounce
1. search搜索联想,用户在不断输入值时,用防抖来节约请求资源
2. window触发resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件,用防抖来让其只触发一次
throttle
1.鼠标不断点击触发,mousedown(单位时间内志触发一次)
2.监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断
六、对嵌套的数组进行扁平化
必须考虑到不同层级的嵌套
ex:stream([1,[2],[3,[4]]])应该返回[1,2,3,4]
1.在for循环中使用递归
function stream(arr) {
var newArr = [];
for(var i = 0;i<arr.length;i++) {
if(!Array.isArra(arr[i])){
newArr.push(arr[i]);
} else {
newArr = newArr.concat(stream(arr[i]));
}
}
return newArr;
}
2.some()方法用于检测数组中的元素是否满足指定条件,会依次执行数组的每个元素
function flatten(arr) {
while(arr.some(item => Array.isArray(item))){
arr = [].concat(...arr)
}
return arr;
}
- some()不会对空数组进行检测
- some()不会改变原始数组 3.es6新增的数组实例方法flat() 4.如果数组中都是字符串,可以利用数组toString()方法