underscore的封装和扩展
// 1. 不污染全局环境
(function() { // 2. 保留之前同名变量
var previousUnderscore = window._; var _ = function(obj) {
return new wrapper(obj);
}; // 模块化
if (typeof define === 'function' && define.amd) {
define('underscore', [], function() {
return _;
});
} else if (typeof exports !== 'undefined') {
if (typeof module !== 'undefined' && module.exports) {
exports = module.exports = _;
}
exports._ = _;
} else {
window['_'] = _;
} // 3. undersocre链式方案
var wrapper = function(obj) {
this._wrapped = obj;
}; // 链式包装函数
var result = function(obj, chain) {
return chain ? _(obj).chain() : obj;
}; // 触发可链式函数
wrapper.prototype.chain = function() {
// this._chain用来标示当前对象是否使用链式操作
this._chain = true;
return this;
}; // 当触发可链式后,用这个来取结果值
wrapper.prototype.value = function() {
return this._wrapped;
}; // 4.将_的静态方法,赋值给_对象
var ArrayProto = Array.prototype,
forEach = ArrayProto.forEach,
push = ArrayProto.push;
_.each = forEach; _.type = function(obj){
return Object.prototype.toString.call(obj).slice(8,-1).toLowerCase();
} _.isFunction = function(fn){
return (_.type(fn) == "function");
} _.functions = function(obj) {
var names = [];
for (var key in obj) {
if (_.isFunction(obj[key])) names.push(key);
}
return names.sort();
} _.mixin = function(obj) {
forEach.call(_.functions(obj), function(name) {
var func = _[name] = obj[name];
_.prototype[name] = function() {
var args = [this._wrapped];
push.apply(args, arguments);
return result( func.apply(_, args),this._chain);
};
});
}; // _是返回wrapper的实例,该实例没有_.protoype的方法
// 所以把 _.prototype 指向了 wrapper.prototype,
// 之后往_.prototype添函数,也就是向wrapper.prototype添函数
_.prototype = wrapper.prototype;
_.prototype.constructor = _;
_.mixin(_); // 5.扩展_对象的方法
// 这些数组方法本身不可链式
forEach.call(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { var method = ArrayProto[name];
wrapper.prototype[name] = function() {
var wrapped = this._wrapped;
// 调用Array对应的方法并返回结果
method.apply(wrapped, arguments);
var length = wrapped.length;
if ((name == 'shift' || name == 'splice') && length === 0) {
delete wrapped[0];
}
return result(wrapped, this._chain);
};
}); // 这些数组方法本身可链式
forEach.call(['concat', 'join', 'slice'], function(name) {
var method = ArrayProto[name];
wrapper.prototype[name] = function() {
return result(method.apply(this._wrapped, arguments), this._chain);
};
}); })(); // 使用实例 // 不可链式方法,使其可链式
// var errorTest = [1,2].push(3).push(4); // push这个函数返回的是函数长度,所以这里会报错
var underscore_obj = _([1, 2]).chain().push(3).push(4);
var result_arr = underscore_obj.value();
console.log(result_arr);
underscore的封装和扩展的更多相关文章
- 一步一步学习underscore的封装和扩展方式
前言 underscore虽然有点过时,这些年要慢慢被Lodash给淘汰或合并. 但通过看它的源码,还是能学到一个库的封装和扩展方式. 第一步,不污染全局环境. ES5中的JS作用域是函数作用域. 函 ...
- 【转】Python基础-封装与扩展、静态方法和类方法
[转]Python基础-封装与扩展.静态方法和类方法 一.封装与扩展 封装在于明确区分内外,使得类实现者可以修改封装内的东西而不影响外部调用者的代码:而外部使用者只知道一个接口(函数),只要接口(函数 ...
- Python基础-封装与扩展、静态方法和类方法
一.封装与扩展 封装在于明确区分内外,使得类实现者可以修改封装内的东西而不影响外部调用者的代码:而外部使用者只知道一个接口(函数),只要接口(函数)名.参数不变,使用者的代码永远无需改变.这就提供一个 ...
- 玩转控件:对Dev中GridControl控件的封装和扩展
又是一年清明节至,细雨绵绵犹如泪光,树叶随风摆动.... 转眼间,一年又过去了三分之一,疫情的严峻让不少企业就跟清明时节的树叶一样,摇摇欲坠.裁员的裁员,降薪的降薪,996的996~~说起来都是泪,以 ...
- Delphi对于控件的SuperClassing(封装并扩展Button,使之变成TButton)
写博客写了这么久,但是一直不知道应该怎么样写函数之间的调用关系和执行顺序,因为不停的跳来跳去的,但是写的时候却只能顺序写调用关系,直到今天发现这种写法很不错: TButton创建窗口是在CreateW ...
- jQuery的封装和扩展方式
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- 对bootstrap modal的简单扩展封装
对bootstrap modal的简单扩展封装 参考自:http://www.muzilei.com/archives/677 注:原文不支持bootstrap新版本,并且居中等存在问题 此段时间 ...
- SwiftyUserDefaults对NSUserDefaults的封装扩展
SwiftyUserDefaults 是对NSUserDefaults的一些封装和扩展,这个库这个只有一个类,操作起来十分简单方便: 这里只有两个步骤来使用SwiftyUserDefaults: st ...
- underscore源码解析 (转载)
转载出自http://www.cnblogs.com/human/p/3273616.html (function() { // 创建一个全局对象, 在浏览器中表示为window对象, 在Node.j ...
随机推荐
- Linux和Windows远程桌面互连
1.Ubuntu 连 windows W.1 Windows设置允许远程桌面连接 U.1 Ubuntu设置 apt-get install rdesktop U.2 Ubuntu连接 ...
- UserSelector兼容
1.更新到asp.net2.0或以上,将Microsoft.Web.UI.TreeView更换为新的System.Web.UI.WebControls.TreeView 2.将UserId,UserT ...
- 【Pro ASP.NET MVC 3 Framework】.学习笔记.7.SportsStore:购物车
3 创建购物车 每个商品旁边都要显示Add to cart按钮.点击按钮后,会显示客户已经选中的商品的摘要,包括总金额.在购物车里,用户可以点击继续购物按钮返回product目录.也可以点击Check ...
- Discuz! X2头部header.htm修改指南
相对于1.5版本,2.0版本并没有在模板机制上做太大改动,基本延续了1.5的模板机制.下面我就为和大家一起过一下X2的头部代码.希望大家对头部代码有些认识. 1.顶部的设为首页,和收藏本站.这里是可以 ...
- 修改ECSHOP系统红包序列号规律
ECSHOP系统线下发放红包时系统生成的红包序列号是在10000的基础上增加四位随机数字.如果当我们要发放大额度红包的时候,这样的序列号规则难免给人不安全的感觉,万一真的有哪个无聊的人,用一天时间来蒙 ...
- div使用jqueryui 源码 | gridview多个功能的源码
div使用jqueryui 源码 | gridview多个功能的源码 一.gridview 选中行 改变颜色,双击选中 改变颜色 protected void gv1_SelectedIndexCha ...
- 20145227《Java程序设计》第1次实验报告
20145227<Java程序设计>第1次实验报告 实验步骤与内容 命令行下Java程序开发 1.打开 cmd ,输入 mkdir 20145227 命令建立实验目录,然后输入 cd 20 ...
- Cocos2dx-lua开发之c++绑定到lua
一. 简单介绍 文章介绍是在实际的游戏开发项目中,将自定义的C++类绑定到lua中,能够让lua调用c++类.会创建一个python脚本,执行python脚本会让自动将我们的c++类绑定到lua.生成 ...
- HDU 2067:小兔的棋盘
小兔的棋盘 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Subm ...
- Reflection实现通用增删改
新增 /// <summary> /// 通用新增方法 /// </summary> /// <param name="arr">一行数据封装的 ...