Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What are the functions of functions

2025-02-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article introduces the relevant knowledge of "what functions have". In the operation process of actual cases, many people will encounter such difficulties. Next, let Xiaobian lead you to learn how to deal with these situations! I hope you can read carefully and learn something!

Functions are dominant in any programming language.

In js, the function is an alternative existence, essentially a special Object, which can set properties:

const fn = () => { }; fn.foo = "foo"; console.log(fn.foo); // 'foo'

Today we share some of the functions:

The buffer function memoize

Curry function curry

intercept parameter processing arg

anti-shake throttle

delay function execution delay

delay function call defer

asynchronous function call compose

The function is called only once.

Determine if the function can be executed

Check object properties checkProp

chain call function

The buffer function memoize

The idea of memoize comes from the Hook documentation of reload, where the feature of memoize is "using the features of functions to cache."

Do not know when you do algorithm, whether to consider recursion is how to cache results, layers of storage.

Fibonacci, where is the cache of each calculation?

const fibonacci = (n) => { return n

< 2 ? n : fibonacci(n - 1) + fibonacci(n - 2); }; 我们可以简单模拟一下memoize的实现: const memoize = function (fn) { const cache = {}; return function () { const key = JSON.stringify(arguments); var value = cache[key]; if (!value) { // 为了了解过程加入的log,正式场合应该去掉 console.log('新值,执行中...'); // 放在一个数组中,方便应对undefined,null等异常情况 value = [fn.apply(this, arguments)]; cache[key] = value; } else { console.log('来自缓存'); } return value[0]; } } 测试一下: const memoizeFibonacci = memoize(fibonacci); const log = console.log; log(memoizeFibonacci(45)); // 新值,执行中...; 1134903170 // 等待时间比较长 log(memoizeFibonacci(45)); // 来自缓存; 1134903170 log(memoizeFibonacci(45)); // 来自缓存; 1134903170 log(memoizeFibonacci(45)); // 来自缓存; 1134903170 log(memoizeFibonacci(45)); 函数柯里化curry 柯里化的概念就是「 把接受多个参数的函数变换成接受一个单一参数的函数 」。 const curry = (fn, arity = fn.length, ...args) =>

arity (...args) => { const next = acc => args => args.reduce((x, y) => x(y), acc); if (n > args.length) throw new RangeError('Arguments too few!'); return next(fn)(args.slice(0, n)); }; const add = x => y => z => x + y + z; const uncurriedAdd = uncurry(add, 3); uncurriedAdd(1, 2, 3); // 6

截取函数参数ary

「 截取指定函数参数做操作 」;ary的第二个参数接收一个索引参数,表示只截取得到n的位置。

// ary 截取指定参数处理 const ary = (fn, n) => (args) => fn(args.slice(0, n)); // 如果处理的数据是字符串 const checkPe = (arg) => { if (arg && arg.indexOf('pe') > -1) { return arg.indexOf('pe') } return -1 } const getPe = ary(checkPe, 5); const numsPe = ['wpe', 'wwperr', 'wwepe'].map(x => getPe(x)); console.log(numsPe, 'numsPe') // [1, 2, 3]

如果是数组的话,需要使用扩展运算符。

// 如果处理的数据是数组 const ary = (fn, n) => (...args) => fn(...args.slice(0, n)); const firstTwoMax = ary(Math.max, 3); const nums = [[2, 6, 9, 'a'], [6, 4, 8], [10]].map(x => firstTwoMax(...x)); console.log(nums, 'nums') // [9, 8, 10]

防抖节流

关于防抖和节流的区别可以参考我之前的文章《电梯与地铁之说》。

const debounce = (fn, ms = 0) => { let timeoutId; return function(...args) { clearTimeout(timeoutId); timeoutId = setTimeout(() => fn.apply(this, args), ms); }; }; window.addEventListener( 'resize', debounce(() => { console.log(window.innerWidth); console.log(window.innerHeight); }, 250)

传入高频次调用的函数和时间间隔,返回一个已防抖的函数。

节流会稀释函数的执行频率。在wait秒内只执行一次。

const throttle = (fn, wait) => { let inThrottle, lastFn, lastTime; return function() { const context = this, args = arguments; if (!inThrottle) { fn.apply(context, args); lastTime = Date.now(); inThrottle = true; } else { clearTimeout(lastFn); lastFn = setTimeout(function() { if (Date.now() - lastTime >= wait) { fn.apply(context, args); lastTime = Date.now(); } }, Math.max(wait - (Date.now() - lastTime), 0)); } }; }; window.addEventListener( 'resize', throttle(function(evt) { console.log(window.innerWidth); console.log(window.innerHeight); }, 250) ); // Will log the window dimensions at most every 250ms

延迟函数执行delay

delay字面意思:「 延迟执行 」。

const delay = (fn, wait, ...args) => setTimeout(fn, wait, ...args); delay( function (text) { console.log(text); }, 1000, 'later' ); // Logs 'later' after one second.

延迟函数调用defer

defer字面意思:「 延迟调用 」。

可适用于推迟 cpu 密集型计算,以免阻塞渲染引擎工作。使用setTimeout(超时时间为1ms)将函数参数添加到浏览器事件队列末尾。

const defer = (fn, ...args) => setTimeout(fn, 1, ...args); // Example A: defer(console.log, 'a'), console.log('b'); // logs 'b' then 'a'

异步函数compose

compose函数是「 从右向左去实现的数据执行流 」。它的真正意义在于逻辑分层。利用reduce方法实现函数的"洋葱"包裹。

const compose = (...fns) => fns.reduce((f, g) => (...args) => f(g(...args))); const substract3 = x => x - 3; const add5 = x => x + 5; const multiply = (x, y) => x * y; const multiplyAndAdd5AndSubstract3 = compose( substract3, add5, multiply ); multiplyAndAdd5AndSubstract3(5, 2); // 12

要想实现从左向右执行也非常简单,把f和g的位置互调一下。

函数只被调用一次once

因为 JavaScript 是单线程执行环境,不需要考虑并发环境,直接一个内部变量存到闭包中,每次调用前判断,并在第一次调用时,修改其值,让后续调用全部失效。

const once = (fn) => { let called = false; return function (...args) { if (called) return; called = true; return fn.apply(this, args); }; }; const startApp = function (event) { console.log(this, event); // document.body, MouseEvent }; document.body.addEventListener("click", once(startApp));

判断函数是否可以执行

第一个参数为函数是否可以执行的判断条件,第二个参数为执行的函数。

const when = (pred, whenTrue) => (x) => (pred(x) ? whenTrue(x) : x); const doubleEvenNumbers = when( (x) => x % 2 === 0, (x) => x * 2 ); doubleEvenNumbers(2); // 4 doubleEvenNumbers(1); // 1

检查对象属性

「 判断某个对象是否具备要求 」。用!!强制转化为布尔类型。

const checkProp = (predicate, prop) => (obj) => !!predicate(obj[prop]); const lengthIs4 = checkProp((l) => l === 4, "length"); lengthIs4([]); // false lengthIs4([1, 2, 3, 4]); // true const sizeIs4 = checkProp((l) => l === 4, "size"); sizeIs4(new Set([1, 2, 3, 4])); // true const session = { obj: { active: true, disabled: false } }; const validUserSession = checkProp((u) => u.active && !u.disabled, "obj"); validUserSession(session); // true

链式调用

将函数数组转换为有决策权的链式函数调用。

const chainAsync = (fns) => { let curr = 0; const last = fns[fns.length - 1]; const next = () => { const fn = fns[curr++]; fn === last ? fn() : fn(next); }; next(); }; chainAsync([ (next) => { console.log("0 seconds"); setTimeout(next, 1000); }, (next) => { console.log("1 second"); setTimeout(next, 1000); }, () => { console.log("2 second"); }, ]);"函数有哪些作用"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report