函数防抖
-
debounce
- search搜索联想,用户在不断输入值时,用防抖来节约请求资源。
- window触发resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件,用防抖来让其只触发一次
// 防抖(一段时间会等,然后带着一起做了)
function debounce(fn, delay){
let timerId = null
return function(){
// 取debounce执行作用域的this
const context = this
if(timerId){window.clearTimeout(timerId)}
timerId = setTimeout(()=>{
fn.apply(context, arguments)
timerId = null
},delay)
}
}
const debounced = debounce(()=>console.log('hi'))
debounced()
函数节流
-
throttle
- 鼠标不断点击触发,mousedown(单位时间内只触发一次)
- 监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断
// 节流(一段时间执行一次之后,就不执行第二次)
function throttle(fn, delay){
let canUse = true
return function(){
if(canUse){
fn.apply(this, arguments)
canUse = false
setTimeout(()=>canUse = true, delay)
}
}
}
const throttled = throttle(()=>console.log('hi'))
throttled()
数组扁平化
const flat = (arr) => {
let arrResult = []
for(let i=0, len=arr.length; i<len; i++){
if(Array.isArray(arr[i])){
arrResult.push(...flat(arr[i]))
// arrResult = arrResult.concat(flat(arr[i]))
}else{
arrResult.push(arr[i])
}
}
return arrResult;
}
flat(arr)
柯里化
function createCurry(func, args) {
var argity = func.length;
var args = args || [];
return function () {
var _args = [].slice.apply(arguments);
args.push(..._args);
if (args.length < argity) {
return createCurry.call(this, func, args);
}
return func.apply(this, args);
}
}
斐波那契数列
let fib = function(n) {
let i = 2
let res = [0,1,1]
while(i <= n) {
res[i] = res[i - 1] + res[i - 2]
i++
}
return res[n]
}
得到一个两数之间的随机整数
这个例子返回了一个在指定值之间的随机整数。这个值不小于 min (如果 min 不是整数,则不小于 min 的向上取整数),且小于(不等于)max。
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min; //不含最大值,含最小值
}
路径总和
var pathSum = function (root, sum) {
if (root === null) return 0
return pathByDFS(root, sum) + pathSum(root.left, sum) + pathSum(root.right, sum)
}
var pathByDFS = function (root, sum) {
if (root === null) return 0
var res = 0
if (root.val === sum) {
res++
}
res += pathByDFS(root.left, sum - root.val)
res += pathByDFS(root.right, sum - root.val)
return res
}
function TreeNode(val) {
this.val = val
this.left = this.right = null
}
AJAX
var request = new XMLHttpRequest()
request.open('GET', '/a/b/c?name=ff', true);
request.onreadystatechange = function () {
if(request.readyState === 4 && request.status === 200) {
console.log(request.responseText);
}};
request.send();
Promise
function Promise(executor) {
let self = this;
self.status = 'pending'; //等待态
self.value = undefined; //成功的返回值
self.reason = undefined; //失败的原因
function resolve(value){
if(self.status === 'pending'){
self.status = 'resolved';
self.value = value;
}
}
function reject(reason) {
if(self.status === 'pending') {
self.status = 'rejected';
self.reason = reason;
}
}
try{
executor(resolve, reject);
}catch(e){
reject(e);// 捕获时发生异常,就直接失败
}
}
//onFufiled 成功的回调
//onRejected 失败的回调
Promise.prototype.then = function (onFufiled, onRejected) {
let self = this;
if(self.status === 'resolved'){
onFufiled(self.value);
}
if(self.status === 'rejected'){
onRejected(self.reason);
}
}
module.exports = Promise;
粗暴深拷贝
function deepCopy(obj1){
let _obj = JSON.stringify(obj1);
let obj2 = JSON.parse(_obj);
return obj2;
}
var a = [1, [1, 2], 3, 4];
var b = deepCopy(a);
async await
async function f() {
try {
await new Promise(function (resolve, reject) {
throw new Error('出错了');
});
}
catch(e) { }
return await('hello world');
}
new 操作符
function myNew(){
const obj = new Object();
Constructor = Array.prototype.shift.call(arguments);
obj.__proto__ = Constructor.prototype;
let ret = Constructor.apply(obj,arguments); // 判断构造函数是否存在返回值
return typeof ret === 'object'? ret : obj;
}