underscore.js 源码学习(一) 大体框架
标签:
JavaScript
// ================立即执行函数================ // 使用(function(){}())立即执行函数,减少全局变量 // ----????----函数声明 function (){} 与函数表达式 var funName = function(){}----????---- // function(){}() 结果会返回Uncaught SyntaxError: Unexpected token ( // 因为此处,编译器会将function当做函数声明关键字去编译,而(并不可以当做函数名 // (function(){}()) 可以正常执行 // 此处function 被挡住表达式编译 // ----????----函数声明 function (){} 与函数表达式 var funName = function(){}----????---- // ~function(){}()/+function(){}()/-function(){}()/!function(){}() // true && function(){}() // 0,function(){} // 以上三种情况下,function都会被当成表达式去编译。 // 所以经常会在一个源码中看到~function写法吧// // ================立即执行函数================ (function(){}( // 创建root变量,保存全局根变量。 // 浏览器window // 服务器global,部分虚拟机this // WebWorker中为self // ================&& ||操作================ // 逻辑与&& 的优先级高于 逻辑非|| // 逻辑与&&为断路逻辑, // 任何一个值var Boolean(var)==false,立即返回var,否则返回最后一个值 // 逻辑非||为短路逻辑, // 任何一个值var Boolean(var)===true,立即返回var,,否则返回最后一个值 // ================&& ||操作================ var root = typeof self == 'object' && self.self === self && self || typeof global == 'object' && global.global === global && global || this || {}; // 保存已存在的全局中_变量,以便避免变量冲突 var previousUnderscore = root._; // Naked function reference for surrogate-prototype-swapping. // https://stackoverflow.com/questions/30496650/what-is-surrogate-prototype-swapping-in-javascript // 关于surrogate-prototype-swapping是什么的理解: // Ctor就是一个裸函数,本身并没有什么特别的,特别之处在于用途 // Ctor用于在baseCreate函数中暂存要继承的原型对象,并构造一个新的对象 var Ctor = function() {}; var nativeCreate = Object.create; // An internal function for creating a new object that inherits from another. // 内部函数,用于构造继承指定对象prototype的新对象 var baseCreate = function(prototype) { if (!_.isObject(prototype)) return {}; if (nativeCreate) return nativeCreate(prototype); //暂存 Ctor.prototype = prototype; var result = new Ctor; //销毁 Ctor.prototype = null; return result; }; // Create a safe reference to the Underscore object for use below. // 创建安全作用域 var _ = function(obj) { //obj在_原型链上 if (obj instanceof _) return obj; //不是,构造一个 if (!(this instanceof _)) return new _(obj); //将underscore对象存在_.wrapped属性上 this._wrapped = obj; }; // Utility Functions // ----------------- // 避免冲突,将原本的_变量重新复制给_ _.noConflict = function() { root._ = previousUnderscore; return this; }; // Export the Underscore object for **Node.js**, with // backwards-compatibility for their old module API. If we're in // the browser, add `_` as a global object. // 在nodejs中导出,兼容旧版本 // nodeTyoe用于检测变量是否为HTML元素 // (`nodeType` is checked to ensure that `module` // and `exports` are not HTML elements.) if (typeof exports != 'undefined' && !exports.nodeType) { if (typeof module != 'undefined' && !module.nodeType && module.exports) { exports = module.exports = _; } exports._ = _; } else { root._ = _; } // AMD registration happens at the end for compatibility with AMD loaders // that may not enforce next-turn semantics on modules. Even though general // practice for AMD registration is to be anonymous, underscore registers // as a named module because, like jQuery, it is a base library that is // popular enough to be bundled in a third party lib, but not be part of // an AMD load request. Those cases could generate an error when an // anonymous define() is called outside of a loader request. // AMD规范导出 if (typeof define == 'function' && define.amd) { define('underscore', [], function() { return _; }); } ))
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦