云服务器

AvalonJS 源码分析(一)

2017-12-15 10:47:38 0

上次主要讲解了avalon的整体框架,以及其模块加载器,那么接下来我们将一步一步讲解接下来的参数(注入)依赖部分,今天使用的源码跟上次分析的一样也是2.16版本。

整体内容介绍:

从我们上一次最后讲解的部分开始,也就是从代码63行到结束,我们所讲的参数(注入)依赖部分是以一个数组的形式引入的,从开始到结束一共有80个模块,这样可以直接以数组下标去直接引入我们所需要的模块。

例如 :__webpack_require__(0);

这里直接加载模块一,也是直接返回我们最终一个的avalon对象

分析一:模块一 和模块二

代码从65到100行,这里都是加载avalon所必须的一些模块,

例如:__webpack_require__(2);

我们暂时先忽略掉这一块,或者等以后再回过头来看这一模块的内容

分析二:模块三

代码从102到300行,作者也做了备注说明此模块是用于修复语言的底层缺陷,例如:

  if (!'司徒正美'.trim) {
        var rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g
        String.prototype.trim = function () {
            return this.replace(rtrim, '')
        }
    }

首先判断String是否存在trim的函数,如不存在就将自定义一个trim 并将其添加到String类的prototype(原型对象)中,目的是为了兼容 ie7/8 不支持trim。

Object.keys = function (object) { //ecma262v5 15.2.3.14
        var theKeys = []
        var skipProto = hasProtoEnumBug && typeof object === 'function'
        if (typeof object === 'string' || (object && object.callee)) {
            for (var i = 0; i < object.length; ++i) {
                theKeys.push(String(i))
            }
        } else {
            for (var name in object) {
                if (!(skipProto && name === 'prototype') &&
                        ohasOwn.call(object, name)) {
                    theKeys.push(String(name))
                }
            }
        }

        if (hasDontEnumBug) {
            var ctor = object.constructor,
                    skipConstructor = ctor && ctor.prototype === object
            for (var j = 0; j < dontEnumsLength; j++) {
                var dontEnum = dontEnums[j]
                if (!(skipConstructor && dontEnum === 'constructor') && ohasOwn.call(object, dontEnum)) {
                    theKeys.push(dontEnum)
                }
            }
        }
        return theKeys
    }

Object.keys()是javascript的一个函数,这个函数返回对象的可枚举属性和方法的名称,是不收集继承自原型链上的,但在IE8下Object的一系列属性是不可遍历的,所以进行改进。在实现的同时,通过对

 dontEnums = ['toString','toLocaleString','valueOf','hasOwnProperty','isPrototypeOf','propertyIsEnumerable','constructor'];

的遍历,去判断继承于原形链上的几个属性是否被重新改写,如被重新改写,则将其返回,修复其对原型链的不兼容。

function iterator(vars, body, ret) {
    var fun = 'for(var '+vars+'i=0,n = this.length;i < n;i++){'+
        body.replace('_', 'fn.call(scope,this[i],i,this)')
        +'}'+ret
    return new Function("fn,scope",fun);
}
//迭代操作,将数组的元素挨个儿传入一个函数中执行。Prototype.js的对应名字为each。
forEach: iterator('', '_', ''),
//迭代类 在数组中的每个项上运行一个函数,如果此函数的值为真,则此元素作为新数组的元素收集起来,并返回新数组
filter: iterator('r=[],j=0,', 'if(_)r[j++]=this[i]', 'return r'),
//收集操作,将数组的元素挨个儿传入一个函数中执行,然后把它们的返回值组成一个新数组返回。Prototype.js的对应名字为collect。
map: iterator('r=[],', 'r[i]=_', 'return r'),
//只要数组中有一个元素满足条件(放进给定函数返回true),那么它就返回true。Prototype.js的对应名字为any。
some: iterator('', 'if(_)return true', 'return false'),
//只有数组中的元素都满足条件(放进给定函数返回true),它才返回true。Prototype.js的对应名字为all。
every: iterator('', 'if(!_)return false', 'return true')

该模块中也对Array的迭代器进行了重写,在上面的例子中,iterator() 有三个参数 - 要调用的函数和传递给该函数的参数。而Function 类可以表示开发者定义的任何函数。用 Function创建函数类时,前面的都是函数参数,只有最后一个参数是函数主体(要执行的代码) 注意:尽管可以使用 Function 构造函数创建函数,但最好不要使用它,因为用它定义函数比用传统方式要慢得多。不过,所有函数都应看作 Function 类的实例。

这一章就先写到这里,下一篇将会继续分析avalon的各个模块。

 

微信关注

获取更多技术咨询