威尼斯wns.9778官网活动_vnsc威尼斯城官网

热门关键词: 威尼斯wns.9778官网活动,vnsc威尼斯城官网
当前位置:威尼斯wns.9778官网活动 > 计算机教程 > underscore源码解析【威尼斯wns.9778官网活动】

underscore源码解析【威尼斯wns.9778官网活动】

文章作者:计算机教程 上传时间:2019-05-10

前言

underscore是最适合初级人士阅读的源码,在阅读源码时,有一些有趣的实现,记录如下。
基于underscore1.8.3。

前言

underscore是最适合初级人士阅读的源码,在阅读源码时,有一些有趣的实现,记录如下。
基于underscore1.8.3。

留存root

// Establish the root object, `window` (`self`) in the browser, `global`
// on the server, or `this` in some virtual machines. We use `self`
// instead of `window` for `WebWorker` support.
var root = typeof self == 'object' && self.self === self && self ||
            typeof global == 'object' && global.global === global && global ||
            this ||
            {};

// Save the previous value of the `_` variable.
var previousUnderscore = root._;

// .......
_.noConflict = function() {
    root._ = previousUnderscore;
    return this;
};

在浏览器情况下,self是window自身的引用。上面的语法主要是为了保证在sever端和服务端都能正常获得根对象。
将root._ 存起来,是为了防止命名冲突。调用noConflict方法,就能把原来的 _ 恢复,然后重新赋值到不冲突的变量上即可。

留存root

// Establish the root object, `window` (`self`) in the browser, `global`
// on the server, or `this` in some virtual machines. We use `self`
// instead of `window` for `WebWorker` support.
var root = typeof self == 'object' && self.self === self && self ||
            typeof global == 'object' && global.global === global && global ||
            this ||
            {};

// Save the previous value of the `_` variable.
var previousUnderscore = root._;

// .......
_.noConflict = function() {
    root._ = previousUnderscore;
    return this;
};

在浏览器情况下,self是window自身的引用。上面的语法主要是为了保证在sever端和服务端都能正常获得根对象。
将root._ 存起来,是为了防止命名冲突。调用noConflict方法,就能把原来的 _ 恢复,然后重新赋值到不冲突的变量上即可。

保留原生方法、减少变量查询

在underscore源码常看到会将一些常用的方法保留起来。

// Save bytes in the minified (but not gzipped) version:
var ArrayProto = Array.prototype, ObjProto = Object.prototype;
var SymbolProto = typeof Symbol !== 'undefined' ? Symbol.prototype : null;

// Create quick reference variables for speed access to core prototypes.
var push = ArrayProto.push,
  slice = ArrayProto.slice,
  toString = ObjProto.toString,
  hasOwnProperty = ObjProto.hasOwnProperty;

这样做的好处有两个:

  1. 减小*.min.js的体积。 在压缩时,some.func1只会被压缩成a.func1。如果把一个对象上常用的方法存为一个变量func1,那么压缩后将节省很多字节。
  2. 加快变量访问速度。
    在实际中,点操作符的使用会使得JavaScript引擎检索该对象下的所有成员。如果嵌套越深,那么读取速度越慢,花费时间越久。如果不是该对象的实例属性,引擎甚至要去检索原型链,将更加耗费时间。

题外话:实际上,为了更好得提高性能,通常将变量保存到局部作用域,检索将会加快。

保留原生方法、减少变量查询

在underscore源码常看到会将一些常用的方法保留起来。

// Save bytes in the minified (but not gzipped) version:
var ArrayProto = Array.prototype, ObjProto = Object.prototype;
var SymbolProto = typeof Symbol !== 'undefined' ? Symbol.prototype : null;

// Create quick reference variables for speed access to core prototypes.
var push = ArrayProto.push,
  slice = ArrayProto.slice,
  toString = ObjProto.toString,
  hasOwnProperty = ObjProto.hasOwnProperty;

这样做的好处有两个:

  1. 减小*威尼斯wns.9778官网活动,.min.js的体积。 在压缩时,some.func1只会被压缩成a.func1。如果把一个对象上常用的方法存为一个变量func1,那么压缩后将节省很多字节。
  2. 加快变量访问速度。
    在实际中,点操作符的使用会使得JavaScript引擎检索该对象下的所有成员。如果嵌套越深,那么读取速度越慢,花费时间越久。如果不是该对象的实例属性,引擎甚至要去检索原型链,将更加耗费时间。

题外话:实际上,为了更好得提高性能,通常将变量保存到局部作用域,检索将会加快。

链式调用

var chainResult = function(instance, obj) {
    // 如果_chain为true,则return一个加了链式属性的underscore对象。
    return instance._chain ? _(obj).chain() : obj;
};
// Add your own custom functions to the Underscore object.
// 可以把自己写的扩展方法通过mixin加入到underscore (_) 上。
_.mixin = function(obj) {
    _.each(_.functions(obj), function(name) {
        var func = _[name] = obj[name];
        _.prototype[name] = function() {
            var args = [this._wrapped];
            push.apply(args, arguments);
            return chainResult(this, func.apply(_, args));
        };
    });
    return _;
};

// Add all of the Underscore functions to the wrapper object.
// 对underscore使用mixin,可以将全部实例方法挂载到原型上。
_.mixin(_);

// 链式调用方法,不过是加了一个Boolean型开关,来对返回值做判断
_.chain = function(obj) {
    var instance = _(obj);
    instance._chain = true;
    return instance;
};

.mixin方法用来把obj上的方法,都内置到下划线 上,相当于jquery的extends方法。
此处调用 _ mixin( _ );实际上,是将 _ 上的方法,都挂载到 _ .prototype上,以便于之后的链式调用。

再来关注一下 .chain这个方法,调用之后会返回一个underscore对象,并且把该对象的 chain属性赋为true。在chainResult这个方法里,会对当前的这个实例的 _ chain属性进行判断,如果调用了chain方法,就认为接下来会进行链式调用,就会将这个实例包裹之后,继续返回。

链式调用的关键就在于,函数return原对象

链式调用

var chainResult = function(instance, obj) {
    // 如果_chain为true,则return一个加了链式属性的underscore对象。
    return instance._chain ? _(obj).chain() : obj;
};
// Add your own custom functions to the Underscore object.
// 可以把自己写的扩展方法通过mixin加入到underscore (_) 上。
_.mixin = function(obj) {
    _.each(_.functions(obj), function(name) {
        var func = _[name] = obj[name];
        _.prototype[name] = function() {
            var args = [this._wrapped];
            push.apply(args, arguments);
            return chainResult(this, func.apply(_, args));
        };
    });
    return _;
};

// Add all of the Underscore functions to the wrapper object.
// 对underscore使用mixin,可以将全部实例方法挂载到原型上。
_.mixin(_);

// 链式调用方法,不过是加了一个Boolean型开关,来对返回值做判断
_.chain = function(obj) {
    var instance = _(obj);
    instance._chain = true;
    return instance;
};

.mixin方法用来把obj上的方法,都内置到下划线 上,相当于jquery的extends方法。
此处调用 _ mixin( _ );实际上,是将 _ 上的方法,都挂载到 _ .prototype上,以便于之后的链式调用。

再来关注一下 .chain这个方法,调用之后会返回一个underscore对象,并且把该对象的 chain属性赋为true。在chainResult这个方法里,会对当前的这个实例的 _ chain属性进行判断,如果调用了chain方法,就认为接下来会进行链式调用,就会将这个实例包裹之后,继续返回。

链式调用的关键就在于,函数return原对象

本文由威尼斯wns.9778官网活动发布于计算机教程,转载请注明出处:underscore源码解析【威尼斯wns.9778官网活动】

关键词: