ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【HZHV】main.js

2022-04-30 13:32:40  阅读:144  来源: 互联网

标签:function return utils ViewModel js options HZHV main id


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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有