11、封装一个函数,完成功能:add(2).multi(9).div(3) 的结果是6。
function add(x) {
return {
multi(y) {
return {
div(z) {
return x*y/z;
}
}
}
};
}
console.log(add(2).multi(9).div(3));
12、封装一个函数,完成功能:add(2).multi(9).div(3).getValue() 的结果是6。
function myCalculator(num){
var result = num;
return {
add:function(n){
result += n;
return this;
},
minus:function(n){
result -= n;
return this;
},
multi:function(n){
result *= n;
return this;
},
div:function(n){
result /= n;
return this;
},
getValue:function(){
return result;
}
}
}
//调用示例:
let oneHundredTwentyOne = myCalculator(121);
console.log(oneHundredTwentyOne.add(1).minus(2).multi(3).div(4).getValue()); // 输出90
let ten = myCalculator(10);
console.log(ten.multi(5).getValue());
console.log(ten.add(2).multi(5).getValue());
console.log(myCalculator(10).multi(5).div(2).getValue());
13、节流
节流是指当一个事件触发的时候,为防止事件的连续频繁触发,设置定时器,达到一种一段事件内只触发一次的效果,在当前事件内不会再次触发,当前事件结束以后,再次触发才有效。 常用在:鼠标不断点击触发和监听滚动事件
function throttle(cb) {
let myTimer = null;
return function(){
if (myTimer != null) {
return;
}
myTimer = setTimeout(function () {
cb();
clearTimeout(myTimer);
myTimer = null;
}, 100)
}
}
14、防抖
防抖是指当一个事件触发的时候, 为防止频繁触发事件, 设置定时器,以达到一种 频繁触发期间不处理, 只有当最后一次连续触发结束以后才处理。 常用在:搜索和window触发resize的时候
function antiShake() {
let myTimer = null;
return function() {
if (myTimer != null) {
clearTimeout(myTimer);
}
myTimer = setTimeout(function () {
// 请求:问后端要数据
console.log("请求");
}, 200)
}
}
15、封装一个queryString函数,支持输入URL来获取query等参数
例如:输入:
www.antgroup.com?name=ant&from=alibaba&job=frontend;
可以得到如下对象:
{name:"ant",from:"alibaba",job:"frontend"}
function queryString(url){
const encodeStr = decodeURIComponent(url);
const str = encodeStr.split("?")[1];//name=ant&from=alibaba&job=frontend&extraInfo={"a":"b","c":"d"}
const arr = str.split("&");
let obj = {};
arr.forEach(item=>{
const [key,value] = item.split("=");
obj[key] = value;
})
return obj;
}
let urlStr = "https://www.antgroup.com?name=ant&from=alibaba&job=frontend&extraInfo=%7B%22a%22%3A%22b%22%2c%22c%22%3A%22d%22%7D";
console.log(queryString(urlStr));
16、实现事件处理器EventEmitter,有如下功能:
const event = new EventEmitter();
• 绑定事件
• event.on(name, callback);
• 取消绑定
• event.off(name);
• 触发事件
• event.trigger(name, data);
第一种:简单实现:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input type="button" value="绑定事件01" onclick="addEvent01()">
<input type="button" value="触发事件01" onclick="triggerEvent01()">
<input type="button" value="解绑事件01" onclick="offEvent01()">
<script>
/*
实现事件处理器EventEmitter,有如下功能
const event = new EventEmitter();
绑定事件
event.on(name, callback);
取消绑定
event.off(name);
触发事件
event.trigger(name, data);
*/
class EventEmitter{
constructor(){
this.events = {};
}
// 绑定事件
on(name,callback){
this.events[name] = callback;
}
// 触发事件
trigger(name, data){
this.events[name] && this.events[name](data);
}
// 取消绑定
off(name){
this.events[name]=undefined;
}
}
let event = new EventEmitter();
function addEvent01(){
// 绑定事件:
event.on("myclick",function(str){
console.log("myclick",str);
});
}
function triggerEvent01(){
// 触发事件
event.trigger("myclick","hehe");
}
function offEvent01(){
event.off("myclick");
}
</script>
</body>
</html>
第二种:进一步改进
// ## **七、实现事件处理器EventEmitter,有如下功能**
// • **const event = new EventEmitter();**
// • **绑定事件**
// • **event.on(name, callback);**
// • **取消绑定**
// • **event.off(name);**
// • **触发事件**
// • **event.emit(name, data);**
class EventEmitter {
constructor(){
this.events = {}
}
on(name,callback){
if(!this.events[name]){
this.events[name] = [];
}
this.events[name].push(callback);
}
emit(name,data){
if(Array.isArray(this.events[name])){
this.events[name].forEach(item=>{
(typeof item === "function") && item(data);
})
}else if(typeof this.events[name] === "function"){
this.events[name](data);
}else{
throw new Error("EventEmitter: 事件不存在");
}
}
off(name,callback){
for(let key in this.events){
if(key===name){
this.events[key] = this.events[key].filter(item=>item!==callback);
break;
}
}
}
}
17、找出数组中第k大和第m大的数字相加之和
/**
找出数组中第k大和第m大的数字相加之和
说明:实现一个方法,找出数组中第k大的和第m大的数字相加之和
示例:
let arr = [1,2,4,4,3,5], k = 2, m = 4
*/
function findTopSum(arr, k, m) {
// 1、另外定义一个数组,对数组进行降序排序。
let arr2 = [...arr];
arr2.sort((a,b)=>b-a);
// 2、求和
let sum = 0;//求和结果
let maxIndex = 0; //最大数的序号
for(let i=0;i<arr2.length;i++){
if(arr2[i-1]!=arr2[i]){
maxIndex++;
}
if(maxIndex==k || maxIndex==m){
sum += arr2[i];
}
}
return sum;
}
let arr = [1,2,4,4,3,5], k = 2, m = 4
// 第2大的数是4,出现2次,第4大的是2,出现1次,所以结果为10
console.log(findTopSum(arr, k, m))
console.log(findTopSum([18,3,22,9,1,22], 1, 3))
18、有效的括号
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合。 每个右括号都有一个对应的相同类型的左括号。
// 示例 1:
// 输入:s = "()"
// 输出:true
// 示例 2:
// 输入:s = "()[]{}"
// 输出:true
// 示例 3:
// 输入:s = "(]"
// 输出:false
// s = "()"
// 输入:s = "()[]{}"
// s = "(]"
// s = "{()[]([])}"
// let arr = []
// 左:尾插,
// 右:和最后一个元素对比,如果成对,那么,尾删,否则,false;
/**
* @param {string} s
* @return {boolean}
*/
var isValid = function(s) {
var leftStr = "{([";
var arr = [];
for(var i=0;i<s.length;i++){
let ch = s.charAt(i);
// if(s.charAt(i)=="(" || s.charAt(i)=="[" || s.charAt(i)=="{" ){
if(leftStr.indexOf(ch)!=-1){//左括号
arr.push(s.charAt(i));
}else{//右括号
// 和最后一个元素对比,如果成对,那么,尾删,否则,false;
let end = arr[arr.length-1];
if((end=="(" && ch==")") || (end=="{" && ch=="}") || (end=="[" && ch=="]") ){
arr.pop();
}else{
return false;
}
}
}
return arr.length===0;
};
扩展:
1、阿里的面试题:
1、传入 urls 数组。返回所有 taobao.com 结尾的链接网页内容。
网页内容可以直接使用getContentByUrl。
async function getContentByUrl(url) {
return new Promise(resolve => {
setTimeout(() => resolve(url + '的网页内容'), 1000)
})
}
const targetUrls = ['https://taobao.com', 'https://baidu.com', 'https://web.taobao.com']
/** 传入 urls 数组。返回所有 taobao.com 结尾的链接网页内容。
* 网页内容可以直接使用getContentByUrl。
*/
async function fetchData(urls) {
// 在这里开始编码
// 1、获取所有taobao.com 结尾的网页链接
let arr = urls.filter(url=>{
let reg = /taobao.com$/;
return reg.test(url);
});
// console.log("arr",arr);
// 2、调用getContentByUrl
return Promise.all(arr.map(url=>getContentByUrl(url)))
}
fetchData(targetUrls).then(result => console.log("result",result))
// 输出:['https://taobao.com的网页内容', 'https://web.taobao.com的网页内容']