上次写过一篇QWrap骨骼的文章,个人认为,想要了解一个库或框架,首先从他的核心思想入手,理解其思想,那么剩余的就仅仅是方法的堆砌。近年比较火的一个jsMVC框架backbone他的核心强依赖库为underscore。

抽空提取了一下他的骨骼,其实主要就是他的链式操作的实现,别个剩下的就是具体函数的实现了,当然对于Underscore函数式也是它的最大亮点,可以好好看下函数的实现。

<!DOCTYPE html>
<html>
<head>
<title> Underscore骨骼 </title>
</head>
<body>
<script type="text/javascript">
// Underscore骨骼
(function () {
    var root = this;
    
    
    var breaker = {};

var ArrayProto = Array.prototype, ObjProto = Object.prototype;

var nativeForEach    = ArrayProto.forEach,
        nativeMap        = ArrayProto.map,
        nativeFilter    = ArrayProto.filter,
        nativeKeys        = Object.keys;

var slice            = ArrayProto.slice,
        unshift            = ArrayProto.unshift,
        hasOwnProperty  = ObjProto.hasOwnProperty;

// 构造函数
    var _ = function (obj) { return new wrapper(obj); };

// 向全局暴露接口
    root._ = _;

// 类型检测
    _.isNumber = function (obj) {
        return !!(obj === 0 || (obj && obj.toExponential && obj.toFixed));
    };
    _.isFunction = function (obj) {
        return !!(obj && obj.constructor && obj.call && obj.apply);
    };

// 遍历扩展
    var each = _.each = _.forEach = function (obj, iterator, context) {
        if (obj === null) return;
        
        if (nativeForEach && obj.forEach === nativeForEach) {
            obj.forEach(iterator, context);
        } else if (_.isNumber(obj.length)) {
            for (var i = 0, l = obj.length; i < l; i++) {
                if (iterator.call(context, obj[i], i, obj) === breaker) return; 
            }
        } else {
            for (var key in obj) {
                if (hasOwnProperty.call(obj, key)) {
                    if (iterator.call(context, obj[key], key, obj) === breaker) return; 
                } 
            }
        }
    };

// 返回对象上面的函数名
    _.functions = _.methods = function (obj) {
        return _.filter(_.keys(obj), function (key) { return _.isFunction(obj[key])}).sort();
    };

// 过滤数组
    _.filter = _.select = function (obj, iterator, context) {
        var results = [];
        if (obj == null) return results; 
        if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
        
        each(obj, function (value, index, list) {
            if (iterator.call(context, value, index, list)) results[results.length] = value; 
        });
        return results;
    };

// 获取key值
    _.keys = nativeKeys || function (obj) {
        if (obj !== Object(obj)) throw new TypeError('Invalid object');
        var keys = [];
        for (var key in obj) if (hasOwnProperty.call(obj, key)) keys[keys.length] = key;
        return keys;
    };

// 用于实验的map方法
    _.map = function (obj, iterator, context) {
        var results = [];
        if (obj == null) return results;
        if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
        each(obj, function (value, index, list) {
            results[results.length] = iterator.call(context, value, index, list);
        });
        return results;
    };

// 链式操作主要部分
    var wrapper = function (obj) { this._wrapped = obj; };

_.prototype = wrapper.prototype;

// 扩展自定义方法到Wrap包装器上
    _.mixin = function (obj) {
        each(_.functions(obj), function (name) {
            addToWrapper(name, _[name] = obj[name]);
        });
    };
    
    // 是否对结果进行链式包装返回
    var result = function (obj, chain) {
        return chain ? _(obj).chain() : obj;
    };

// 将方法扩展到包装器的原型上
    var addToWrapper = function (name, func) {
        wrapper.prototype[name] = function () {
            var args = slice.call(arguments);
            unshift.call(args, this._wrapped);
            return result(func.apply(_, args), this._chain);
        };
    };

// 将所有Underscore上的方法添加到Wrap包装器上
    _.mixin(_);

// 扩展Array上的方法到wrap包装器上-包装原数组
    each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function (name) {
        var method = ArrayProto[name];
        wrapper.prototype[name] = function () {
            method.apply(this._wrapped, arguments);
            return result(this._wrapped, this._chain);
        };
    });
    
    // 扩展Array上的方法到wrap包装器上-包装返回值
    each(['concat', 'join', 'slice'], function (name) {
        var method = ArrayProto[name];
        wrapper.prototype[name] = function () {
            return result(method.apply(this._wrapped, arguments), this._chain);
        };
    });

// 添加链式方法的实现
    wrapper.prototype.chain = function () {
        this._chain = true;
        return this;
    };

// 提取链式包装的内容
    wrapper.prototype.value = function () {
        return this._wrapped;
    };

})();

// 结果测试 步骤:将数组[1,2,3]进行链式包装,然后将其用val * 2来map,紧接着用filter进行val < 5过滤, 
// 然后pop,concat最后获取其值value
var re = _([1,2,3]).chain().map(function (val) {
    return val * 2;
}).filter(function (val) {
    return val < 5;
}).pop().concat(['5']).value();

alert(re);
</script>
</body>

< /html>

转载于:https://www.cnblogs.com/bluedream2009/archive/2011/07/02/2096309.html

Underscore骨骼相关推荐

  1. mixamo网站FBX模型带骨骼绑定动作库

    mixamo网站FBX模型带骨骼绑定动作库,unity游戏各职业人物动画,兼容3dmax maya c4d iclone blender等主流3D软件 mixamo游戏3D模型带骨骼绑定FBX动作库 ...

  2. 打造属于自己的underscore系列 ( 一 )

    underscore作为开发中比较常用的一个javascript工具库,提供了一套丰富的函数式编程功能,该库并没有拓展原有的javascript原生对象,而是在自定义的_对象上,提供了100多个方法函 ...

  3. Away3d 骨骼动画优化

    很多朋友说Away3D 的骨骼数限制在32根,确切的说应该是Stage3D 的限制.在 AGAL2.0之前 VC寄存器是128个,每个vc常量寄存器最大只能容纳4位,transform占用一个4*4的 ...

  4. Cocos2d-x 3.8.1+Cocos Studio 2.3.2捉虫记之控制场景文件中的骨骼动画

    Cocos2d-x 3.8.1+Cocos Studio 2.3.2捉虫记之控制场景文件中的骨骼动画 引子 这段时间一直努力在把早期版本的拇指接龙游戏(Cocos2d-x 2.2.3+CocoStud ...

  5. unity 骨骼击碎_保证击碎$ 100挑战的创新策略

    unity 骨骼击碎 by Glenn Gonda 由Glenn Gonda 保证击碎$ 100挑战的创新策略 (A Creative Strategy Guaranteed to Crush the ...

  6. 打造属于自己的underscore系列(五)- 偏函数和函数柯里化

    这一节的内容,主要针对javascript函数式编程的两个重要概念,偏函数(partial application) 和函数柯里化(curry)进行介绍.着重讲解underscore中对于偏函数应用的 ...

  7. Kinect 骨骼追踪数据的处理方法

    http://www.ituring.com.cn/article/196144 作者/ 吴国斌 博士,PMP,微软亚洲研究院学术合作经理.负责中国高校及科研机构Kinect for Windows学 ...

  8. 亦正亦邪,骨骼惊奇的LGG

    文章目录 亦正亦邪,骨骼惊奇的LGG 对急性肠胃炎没啥用 帮助生骨 未来可期 作者简介 猜你喜欢 写在后面 亦正亦邪,骨骼惊奇的LGG LGG,这既不是你家雪地靴UGG的山寨品牌,也不是"老 ...

  9. 3dsmax biped 骨骼的创建和修改

    3dsmax biped 骨骼的创建和修改 创建 修改

  10. 3dsmax biped 骨骼姿势 对称操作

    3dsmax biped 骨骼姿势 对称操作

最新文章

  1. 怎么测内阻 恒压源_电池内阻及简单测试方法
  2. OpenGL之macOS上的环境搭建
  3. 大前端完整学习路线(完整版),路线完整版
  4. Nim游戏(初谈博弈)
  5. Codeforces Round #402 D String Game(二分)
  6. MySQL_数据库表结构的操作
  7. 开发环境很重要,需要学习如何自己搭建开发环境
  8. 聊聊我对写好程序的认识
  9. 华为奇葩面试题:一头牛重800公斤一座桥承重700公斤,请问牛怎么过桥?
  10. mac上iphone4刷机与越狱(二)
  11. TS入门——01.数据类型
  12. 扑克牌发牌游戏python_Python随机扑克牌生成器游戏
  13. 锁定计算机后 360wifi,如何使360wifi关闭电脑后继续使?
  14. 听听那冷雨 -- 余光中
  15. P3545 [POI2012]HUR-Warehouse Store
  16. javaS的tring和androidS的tring区别是什么?
  17. 我的软件销售生涯(一)
  18. PACT: PARAMETERIZED CLIPPING ACTIVATION FOR QUANTIZED NEURAL NETWORKS 论文学习
  19. Cmake编译配置opencv3.3+contrib+cuda7.5
  20. 3W字经验总结,告诉你如何准备校招!

热门文章

  1. 联通沃云服务器型号,云服务器
  2. Unable to find a @SpringBootConfiguration, you need to use @ContextConfiguration or @SpringBootTest(
  3. 二十五、JAVA多线程(一、理论知识)
  4. 安装centos7 Minimal后 开启远程SSH
  5. Oracle 方言 PL/SQL 编程
  6. Google Gson API 介绍与使用
  7. 超市商品购买与管理系统
  8. Podfile使用说明
  9. 算法手记 之 数据结构(并查集详解)(POJ1703)
  10. 从字节理解Unicode(UTF8/UTF16)