其他分享
首页 > 其他分享> > 【HZHV】main.js

【HZHV】main.js

作者:互联网

main.js源码

将英文注释用中文进行注释

点击查看代码
var config      = require('./config'),
    ViewModel   = require('./viewmodel'),
    directives  = require('./directives'),
    filters     = require('./filters'),
    utils       = require('./utils')

/**
 *  Set config options
 *  设置配置选项
 */
ViewModel.config = function (opts) {
    if (opts) {
        utils.extend(config, opts)
        if (opts.prefix) updatePrefix()
    }
    return this
}

/**
 *  Allows user to register/retrieve a directive definition
 *  允许用户注册/检索指令定义
 */
ViewModel.directive = function (id, fn) {
    if (!fn) return directives[id]
    directives[id] = fn
    return this
}

/**
 *  Allows user to register/retrieve a filter function
 *  允许用户注册/检索筛选函数
 */
ViewModel.filter = function (id, fn) {
    if (!fn) return filters[id]
    filters[id] = fn
    return this
}

/**
 *  Allows user to register/retrieve a ViewModel constructor
 *  允许用户注册/检索ViewModel构造函数
 */
ViewModel.component = function (id, Ctor) {
    if (!Ctor) return utils.components[id]
    utils.components[id] = utils.toConstructor(Ctor)
    return this
}

/**
 *  Allows user to register/retrieve a Custom element constructor
 *  允许用户注册/检索自定义元素构造函数
 */
ViewModel.element = function (id, Ctor) {
    if (!Ctor) return utils.elements[id]
    utils.elements[id] = utils.toConstructor(Ctor)
    return this
}

/**
 *  Allows user to register/retrieve a template partial
 *  允许用户注册/检索部分模板
 */
ViewModel.partial = function (id, partial) {
    if (!partial) return utils.partials[id]
    utils.partials[id] = utils.toFragment(partial)
    return this
}

/**
 *  Allows user to register/retrieve a transition definition object
 *  允许用户注册/检索转换定义对象
 */
ViewModel.transition = function (id, transition) {
    if (!transition) return utils.transitions[id]
    utils.transitions[id] = transition
    return this
}

ViewModel.extend = extend

/**
 *  Expose the main ViewModel class
 *  and add extend method
 *  公开主ViewModel类并添加extend方法
 */
function extend (options) {

    var ParentVM = this

    // inherit options
    // 继承选项
    options = inheritOptions(options, ParentVM.options, true)
    utils.processOptions(options)

    var ExtendedVM = function (opts) {
        opts = inheritOptions(opts, options, true)
        ParentVM.call(this, opts)
    }

    // inherit prototype props
    // 继承原型props属性
    var proto = ExtendedVM.prototype = Object.create(ParentVM.prototype)
    utils.defProtected(proto, 'constructor', ExtendedVM)

    // copy prototype props
    // 复制原型props属性
    var protoMixins = options.proto
    if (protoMixins) {
        for (var key in protoMixins) {
            if (!(key in ViewModel.prototype)) {
                proto[key] = protoMixins[key]
            }
        }
    }

    // allow extended VM to be further extended
    // 允许扩展VM进一步扩展
    ExtendedVM.extend = extend
    ExtendedVM.super = ParentVM
    ExtendedVM.options = options
    return ExtendedVM
}

/**
 *  Inherit options
 *  继承选项
 *
 *  For options such as `scope`, `vms`, `directives`, 'partials',
 *  they should be further extended. However extending should only
 *  be done at top level.
 *  对于'scope'、'vms'、'directives'、'partials'等选项,它们应该进一步扩展。
 *  然而,扩展只能在顶层完成。
 * 
 *  `proto` is an exception because it's handled directly on the
 *  prototype.
 *  `proto`是一个例外,因为它直接在原型上处理。
 *
 *  `el` is an exception because it's not allowed as an
 *  extension option, but only as an instance option.
 *  `el`是一个例外,因为它不允许作为扩展选项,而只能作为实例选项。
 */
function inheritOptions (child, parent, topLevel) {
    child = child || utils.hash()
    if (!parent) return child
    for (var key in parent) {
        if (key === 'el' || key === 'proto') continue
        if (!child[key]) { // child has priority
            child[key] = parent[key]
        } else if (topLevel && utils.typeOf(child[key]) === 'Object') {
            inheritOptions(child[key], parent[key], false)
        }
    }
    return child
}

/**
 *  Update prefix for some special directives
 *  that are used in compilation.
 *  更新编译中使用的某些特殊指令的前缀。
 */
var specialAttributes = [
    'id',
    'pre',
    'text',
    'repeat',
    'partial',
    'component',
    'transition'
]

function updatePrefix () {
    specialAttributes.forEach(setPrefix)
}

function setPrefix (attr) {
    config.attrs[attr] = config.prefix + '-' + attr
}

updatePrefix()
module.exports = ViewModel

逐行剖析

第1 ~ 5行

require方法

requirenode 用来加载并执行其它文件导出的模块的方法。
NodeJs 中,我们引入的任何一个模块都对应一个 Module 实例,包括入口文件。

【评】新建变量将加载进来的文件然后赋值给变量。我们可以看到在源码目录下是有这些文件的。

image

第7 ~ 79行

提出问题

【评】这部分主要对ViewModel对象的一些属性进行赋值操作。为什么说是ViewModel对象呢?因为我看到了ViewModel.key这种形式,那么ViewModel就是一个对象,(.)点运算后面跟着就是属性。但是不知道ViewModel对象这些属性是怎么来的。是不是新建的呢?这个过程是赋值过程,会不会对ViewModel对象这些初始化呢?带着这些疑问,于是我做了以下实验:

实验代码

点击查看代码
var ViewModel = {};

ViewModel.config = function (opts) {
    if (opts) {
        utils.extend(config, opts)
        if (opts.prefix) updatePrefix()
    }
    return this
}

ViewModel.directive = function (id, fn) {
    if (!fn) return directives[id]
    directives[id] = fn
    return this
}

ViewModel.filter = function (id, fn) {
    if (!fn) return filters[id]
    filters[id] = fn
    return this
}

ViewModel.component = function (id, Ctor) {
    if (!Ctor) return utils.components[id]
    utils.components[id] = utils.toConstructor(Ctor)
    return this
}

ViewModel.element = function (id, Ctor) {
    if (!Ctor) return utils.elements[id]
    utils.elements[id] = utils.toConstructor(Ctor)
    return this
}

ViewModel.transition = function (id, transition) {
    if (!transition) return utils.transitions[id]
    utils.transitions[id] = transition
    return this
}

ViewModel.extend = extend;

function extend (options) {

    var ParentVM = this

    // inherit options
    // 继承选项
    options = inheritOptions(options, ParentVM.options, true)
    utils.processOptions(options)

    var ExtendedVM = function (opts) {
        opts = inheritOptions(opts, options, true)
        ParentVM.call(this, opts)
    }

    // inherit prototype props
    // 继承原型props属性
    var proto = ExtendedVM.prototype = Object.create(ParentVM.prototype)
    utils.defProtected(proto, 'constructor', ExtendedVM)

    // copy prototype props
    // 复制原型props属性
    var protoMixins = options.proto
    if (protoMixins) {
        for (var key in protoMixins) {
            if (!(key in ViewModel.prototype)) {
                proto[key] = protoMixins[key]
            }
        }
    }

    // allow extended VM to be further extended
    // 允许扩展VM进一步扩展
    ExtendedVM.extend = extend
    ExtendedVM.super = ParentVM
    ExtendedVM.options = options
    return ExtendedVM
}

console.log("ViewModel对象这些属性的数据类型:");
console.log("config属性的数据类型:" + (typeof ViewModel.config));
console.log("directive属性的数据类型:" + (typeof ViewModel.directive));
console.log("filter属性的数据类型:" + (typeof ViewModel.filter));
console.log("component属性的数据类型:" + (typeof ViewModel.component));
console.log("element属性的数据类型:" + (typeof ViewModel.element));
console.log("transition属性的数据类型:" + (typeof ViewModel.transition));
console.log("extend属性的数据类型:" + (typeof ViewModel.extend));

实验结果

[Running] node "e:\HMV\JavaScript\JavaScript.js"
ViewModel对象这些属性的数据类型:
config属性的数据类型:function
directive属性的数据类型:function
filter属性的数据类型:function
component属性的数据类型:function
element属性的数据类型:function
transition属性的数据类型:function
extend属性的数据类型:function

[Done] exited with code=0 in 0.18 seconds

实验解释

【评】在上面的实验,我假设ViewModel是一个空对象,因为根据上面的推断,它是一个对象,但是具体是啥不太清楚,所以就先假设它是最简单的空对象。然后把这些属性的代码块全部拎出来,再使用console.log()方法加上typeof运算符,最后看看打印出来的是什么,还有这些属性的数据类型是什么?在实验结果,我们可以看到这些属性的数据类型都是函数。

ViewModel.config

/**
 *  Set config options
 *  设置配置选项
 */
ViewModel.config = function (opts) {
    if (opts) {
        utils.extend(config, opts)
        if (opts.prefix) updatePrefix()
    }
    return this
}

【评】将带形式参数opts的匿名函数赋值给ViewModel对象的config属性。如果选项变量opts为真,如果opts.prefix为真,调用updatePrefix()。

var opts1 = '';
var opts2 = '黄子涵';
var opts3 = true;
var opts4 = false; 

if(opts1) {
    console.log("成功打印opts1");
}

if(opts2) {
    console.log("成功打印opts2");
}

if(opts3) {
    console.log("成功打印opts3");
}

if(opts4) {
    console.log("成功打印opts4");
}

image

【评】这里调用了utils对象的extend属性,这个属性是一个方法,具体函数如下:

/**
     *  simple extend
     *  简单扩展
     */
    extend: function (obj, ext, protective) {
        for (var key in ext) {
            if (protective && obj[key]) continue
            obj[key] = ext[key]
        }
    }

ViewModel.directive

/**
 *  Allows user to register/retrieve a directive definition
 *  允许用户注册/检索指令定义
 */
ViewModel.directive = function (id, fn) {
    if (!fn) return directives[id]
    directives[id] = fn
    return this
}

【评】

ViewModel.filter

/**
 *  Allows user to register/retrieve a filter function
 *  允许用户注册/检索筛选函数
 */
ViewModel.filter = function (id, fn) {
    if (!fn) return filters[id]
    filters[id] = fn
    return this
}

【评】

ViewModel.component

/**
 *  Allows user to register/retrieve a ViewModel constructor
 *  允许用户注册/检索ViewModel构造函数
 */
ViewModel.component = function (id, Ctor) {
    if (!Ctor) return utils.components[id]
    utils.components[id] = utils.toConstructor(Ctor)
    return this
}

ViewModel.element

/**
 *  Allows user to register/retrieve a Custom element constructor
 *  允许用户注册/检索自定义元素构造函数
 */
ViewModel.element = function (id, Ctor) {
    if (!Ctor) return utils.elements[id]
    utils.elements[id] = utils.toConstructor(Ctor)
    return this
}

【评】

ViewModel.partial

/**
 *  Allows user to register/retrieve a template partial
 *  允许用户注册/检索部分模板
 */
ViewModel.partial = function (id, partial) {
    if (!partial) return utils.partials[id]
    utils.partials[id] = utils.toFragment(partial)
    return this
}

【评】

ViewModel.transition

/**
 *  Allows user to register/retrieve a transition definition object
 *  允许用户注册/检索转换定义对象
 */
ViewModel.transition = function (id, transition) {
    if (!transition) return utils.transitions[id]
    utils.transitions[id] = transition
    return this
}

【评】

ViewModel.extend

ViewModel.extend = extend

【评】

extend 函数

/**
 *  Expose the main ViewModel class
 *  and add extend method
 *  公开主ViewModel类并添加extend方法
 */
function extend (options) {

    var ParentVM = this

    // inherit options
    // 继承选项
    options = inheritOptions(options, ParentVM.options, true)
    utils.processOptions(options)

    var ExtendedVM = function (opts) {
        opts = inheritOptions(opts, options, true)
        ParentVM.call(this, opts)
    }

    // inherit prototype props
    // 继承原型props属性
    var proto = ExtendedVM.prototype = Object.create(ParentVM.prototype)
    utils.defProtected(proto, 'constructor', ExtendedVM)

    // copy prototype props
    // 复制原型props属性
    var protoMixins = options.proto
    if (protoMixins) {
        for (var key in protoMixins) {
            if (!(key in ViewModel.prototype)) {
                proto[key] = protoMixins[key]
            }
        }
    }

    // allow extended VM to be further extended
    // 允许扩展VM进一步扩展
    ExtendedVM.extend = extend
    ExtendedVM.super = ParentVM
    ExtendedVM.options = options
    return ExtendedVM
}

【评】

inheritOptions 函数

/**
 *  Inherit options
 *  继承选项
 *
 *  For options such as `scope`, `vms`, `directives`, 'partials',
 *  they should be further extended. However extending should only
 *  be done at top level.
 *  对于'scope'、'vms'、'directives'、'partials'等选项,它们应该进一步扩展。
 *  然而,扩展只能在顶层完成。
 * 
 *  `proto` is an exception because it's handled directly on the
 *  prototype.
 *  `proto`是一个例外,因为它直接在原型上处理。
 *
 *  `el` is an exception because it's not allowed as an
 *  extension option, but only as an instance option.
 *  `el`是一个例外,因为它不允许作为扩展选项,而只能作为实例选项。
 */
function inheritOptions (child, parent, topLevel) {
    child = child || utils.hash()
    if (!parent) return child
    for (var key in parent) {
        if (key === 'el' || key === 'proto') continue
        if (!child[key]) { // child has priority
            child[key] = parent[key]
        } else if (topLevel && utils.typeOf(child[key]) === 'Object') {
            inheritOptions(child[key], parent[key], false)
        }
    }
    return child
}

【评】新建带三个形式参数child,parent,topLevel的inheritOptions函数。

specialAttributes 数组

/**
 *  Update prefix for some special directives
 *  that are used in compilation.
 *  更新编译中使用的某些特殊指令的前缀。
 */
var specialAttributes = [
    'id',
    'pre',
    'text',
    'repeat',
    'partial',
    'component',
    'transition'
]

【评】新建specialAttributes数组,根据变量名的意思,这个数据存储的是一些特殊的属性,这个数组的元素数据类型是字符串,这些元素分别是id、pre、text、repeat、partial、component、transition。

updatePrefix 函数

function updatePrefix () {
    specialAttributes.forEach(setPrefix)
}

【评】新建updatePrefix函数

setPrefix 函数

function setPrefix (attr) {
    config.attrs[attr] = config.prefix + '-' + attr
}

【评】新建带形式参数attr的setPrefix函数

第179 ~ 180行

updatePrefix()
module.exports = ViewModel

【评】调用updatePrefix函数

标签:function,return,utils,ViewModel,js,options,HZHV,main,id
来源: https://www.cnblogs.com/Huang-zihan/p/16195937.html