JS性能优化之函数唯一标识以及自记忆函数

历史小剧场

朱元璋在平定天下前,曾向谋士征求意见。有一位名叫朱升的学者,告诉朱元璋"高筑墙,广积粮,缓称王"。这条策略在朱元璋最终取得胜利的道路中发挥了重要的作用。

知识铺垫

函数可以像对象一样,动态创建和分配属性
对象拥有的,函数都有
唯一的区别是:函数是可调用的,即函数会被调用然后去执行某项动作

  • 函数可以通过字面量来创建
js 复制代码
function fn () {}
  • 函数可以赋值给变量、数组项,或其他对象的属性。
js 复制代码
const fn2 = function () {}

const arr2 = []
arr2.push(fn2)

const obj2 = {}
obj2.fn = fn2;
  • 函数可以作为函数的入参和出参。
js 复制代码
function fn3 (callback) {
  callback()
}
fn3(() => console.log('hello'))
  • 函数可以动态创建和分配属性
js 复制代码
function fn4 () {}
fn4.name = 'fn4'
fn4.age = 18
console.log(fn4) //[Function: fn4] { age: 18 }

函数唯一标识

给函数设置一个 id 属性,作为唯一标识,在某些情况下可以提高性能,比如,

一个集合中的函数,不希望出现重复函数。

js 复制代码
const store = {
    nextId: 1,
    cache: {},
    add(fn) {
        console.log("fn.id => ", fn.id)
        if (!fn.id) {
            fn.id = store.nextId++
            this.cache[fn.id] = fn
        }
    }
}
const fun1 = function () {}
const fun2 = function () {}
store.add(fun1)
store.add(fun1)
store.add(fun2)
console.log(store.cache)  // { '1': [Function: fun1] { id: 1 }, '2': [Function: fun2] { id: 2 } }

注意:ES6 的箭头函数是一种匿名函数的简写,它们不具有自己的 this、arguments、super 或 new.target。由于箭头函数的特性,它们不支持添加属性。

自记忆函数

过给函数添加属性来记住一些计算结果,之后再调用的时候就可以不用重新计算了,直接去属性中的数据,提高性能。(类似于缓存)以计算素数为例

js 复制代码
function isPrime(value) {
    if (!isPrime.cache) {
        // 给函数添加一个 cache 来存储计算结果
        isPrime.cache = {}
    }
    if (isPrime.cache[value] !== undefined) {
        console.log(`命中缓存${value},直接返回${isPrime.cache[value]}`)
        return isPrime.cache[value]
    }
    let prime = value > 2;
    for (let i = 2; i < value; i++) {
        if (value % i === 0) {
            prime = false;
            break;
        }
    }
    console.log(`缓存里没有${value},结果${prime}存进去`)
    return isPrime.cache[value] = prime;  // 先执行 isPrime.cache[value] = prime, 然后执行 return isPrime.cache[value]
}
isPrime(3) // 缓存里没有3,结果true存进去
isPrime(4) // 缓存里没有4,结果false存进去
isPrime(5) // 缓存里没有5,结果true存进去
isPrime(10) // 缓存里没有10,结果false存进去
isPrime(10) // 命中缓存10,直接返回false
isPrime(5) // 命中缓存5,直接返回true
相关推荐
90后的晨仔11 分钟前
深入浅出 Vue 的 computed:不仅仅是“计算属性”那么简单!
前端·vue.js
Nan_Shu_61426 分钟前
学习:入门uniapp Vue3组合式API版本(17)
前端·vue.js·学习·uni-app
止观止1 小时前
Remix框架:高性能React全栈开发实战
前端·react.js·前端框架·remix
萌萌哒草头将军1 小时前
🚀🚀🚀 深入探索 Node.js v22.18.0 新特性;默认支持运行 ts 文件了!
前端·typescript·node.js
安心不心安2 小时前
React ahooks——副作用类hooks之useThrottleFn
前端·javascript·react.js
秋田君2 小时前
Vue3 + WebSocket网页接入弹窗客服功能的完整实现
前端·javascript·websocket·网络协议·学习
浪里行舟2 小时前
一网打尽 Promise 组合技:race vs any, all vs allSettled,再也不迷糊!
前端·javascript·vue.js
Antonio9152 小时前
【网络编程】WebSocket 实现简易Web多人聊天室
前端·网络·c++·websocket
德育处主任Pro3 小时前
p5.js 用 beginGeometry () 和 endGeometry () 打造自定义 3D 模型
开发语言·javascript·3d
tianzhiyi1989sq3 小时前
Vue3 Composition API
前端·javascript·vue.js