// ================立即执行函数================
// 使用(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 _;
});
}
))
打开App,阅读手记