原型链-柯里化-记忆缓存

本文深入探讨了JavaScript中的高级特性,包括原型链的使用、继承机制的细节、函数柯里化的应用以及记忆缓存的设计实现。通过具体代码示例,帮助读者理解这些概念,并展示了如何在实际开发中有效利用它们。

1、 使用原生js实现–原型链使用

(10).add(10).reduce(2).add(10) //28

Number.prototype.add = function(num) {
        return this + num;
    }
    Number.prototype.reduce = function(num) {
        return this - num;
    }
    var res = (10).add(10).reduce(2).add(10);
    console.log(res);

2、 继承遇到的坑

<script>    
        function Tree(){

        }
        Tree.prototype.moreLeafs=function(){
            // this.leaf++;
            console.log(this);
            console.log(this.leaf);
        }
        Tree.prototype.leaf=2;

        var t1 = new Tree();
        t1.moreLeafs();
        t1.moreLeafs();

        var t2 = new Tree();
        t2.moreLeafs();

        t1.leaf == t2.leaf; //false
        t1.moreLeafs == t2.moreLeafs; //true
    </script>

答案是:1,2,1。红宝书中有这样一段话:对象实例访问保存在原型中的值,但却不能通过对象实例重写原型中的值。如果我们在实例中添加了一个属性,而该属性与实例原型中的一个属性同名,那我们就在实例中创建该属性,该属性会屏蔽原型中的那个属性。

3、函数柯里化

如下代码:
var fn=function(a,b,c){
    return a+b+c;
}
需要写一个函数,满足curry(fn)(1)(2)(3) //6

这题很明显,考察函数的柯里化,函数的柯里化还不懂是啥的童鞋可以看这里。
按照题目的要求需要把fn作为第一个参数传进去,而且给出结果刚好是fn运算后给出的结果。
所以我的思路是要有一个函数将fn函数所需参数全部集中到一个数组上,集中完毕后调用fn函数,我的代码如下:

var fn = function(a,b,c) {
    return a+b+c;
}

function curry(fn) {
    var arr = [],
    mySlice = arr.slice
    fnLen = fn.length;

    function curring() {
        arr = arr.concat(mySlice.call(arguments));
        if(arr.length < fnLen) {
            return curring;
        }
        return fn.apply(this, arr);
    }
    return curring
}
curry(fn)(1)(2)(3);//6

bind函数是柯里化的一个用法。

4、记忆缓存

函数可以将先前操作的结果记录在某个对象里,从而避免无谓的重复运算。主要使用 闭包及缓存数组 实现。

方法一采用类似于jQuery缓存的方法,使用对象存储键值对,用闭包封装起来。对于一些有容量限制的可以做超容处理。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <script>
    // 方法一
    /* 创建缓存数组 */
    function createCache() {
        var cache = {}; //对象
        return function(key, value) {
            if (value !== undefined) { //如果存在值,则为设置key的值为value
                cache[key] = value;
                return cache[key];
            } else { //如果value为undefined,则为获取值
                return cache[key];
            }
        }
    }

    //以斐波那契为例
    var count = 0;
    function fib() {
        var cache = createCache();
        function cacheFib(n) {
            if (cache(n) !== undefined) {
                return cache(n);
            } else {
                count++;
                if (n <= 2) {
                    cache(n, 1);
                    return 1;
                }
                var temp = cacheFib(n - 1) + cacheFib(n - 2);
                cache(n, temp);
                return temp;
            }
        }
        return cacheFib;
    }
    var myfib = new fib();
    console.log(myfib(9)); //34
    console.log(count); //9

    </script>
</body>
</html>

方法一扩展:超容处理的createCache方法:

    /* 创建缓存数组-限制缓存大小 */
    function createCache() {
        var cache = {}; //做缓存对象,以键值对的形式存储
        var index = []; //存储键,键有顺序,方便做超容处理
        return function(key, value) {
            if (value !== undefined) { //如果存在值,则为设置key的值为value
                cache[key] = value; //将键值存储在缓存对象中,做缓存
                index.push(key); //将键存储在index数组中,和cache对应
                if (index.length >= 50){
                    //如果超出容量,则删除最早进入缓存的数据
                    var temp = index.shift();
                    delete cache[temp];
                }
                return cache[key];
            } else { //如果value为undefined,则为获取值
                return cache[key];
            }
        }
    }

cache缓存
作用:存储常用数据,提供使用,提升性能
原理:使用对象,以键值对形式存储;使用数组存储键,键有顺序,超出缓存容量,则删除最早进入缓存的一个(即数组第一个);使用闭包封装函数

jQuery的缓存处理:

 function createCache() {
     var keys = [];
     function cache( key, value ) {
         // 使用(key + " ") 是为了避免和原生(本地)的原型中的属性冲突
         if ( keys.push( key + " " ) > 3 ) {
              // 只保留最新存入的数据
              delete cache[ keys.shift() ];
         }
         // 1 给 cache 赋值
         // 2 把value返回
         return (cache[ key + " " ] = value);
     }
     return cache;
}

var typeCache = createCache();
typeCache("monitor");
console.log(typeCache["monitor" + " "]); //undefined

typeCache("monitor1","张");
console.log(typeCache["monitor1" + " "]); //张

typeCache("monitor2","刘");
console.log(typeCache["monitor2" + " "]); //刘

typeCache("monitor3","彭");
console.log(typeCache["monitor3 "]); //彭

console.log(typeCache["monitor "]); ////undefined

方法二来自《js语言精粹》,提供了一个简短精悍的memorizer方法,对于不同的需要记忆的函数可以复用,比如斐波那契函数、阶乘函数。

// --------------------------------方法二:记忆函数-精简写法
    var count1=0;
    var memoizer = function(memo, formula) {
        var recur = function(n) {
            var result = memo[n];
            if (typeof result !== 'number') {
                result = formula(recur, n);
                memo[n] = result;
            }
            return result;
        };
        return recur;
    }

    //斐波那契函数
    var fibonacci = memoizer([0, 1], function(recur, n) {
        count1++;
        return recur(n - 1) + recur(n - 2);
    });
    console.log(fibonacci(9)); //34
    console.log(count1); //8

    //阶乘函数
    var factorial = memoizer([1,1],function(recur,n){
        return n*recur(n-1);
    });
    console.log(factorial(5)); //120
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值