utils.js源码
点击查看代码
var config = require('./config'),
attrs = config.attrs,
toString = Object.prototype.toString,
join = Array.prototype.join,
console = window.console,
ViewModel // late def
/**
* Create a prototype-less object
* which is a better hash/map
*
* 创建一个prototype-less对象,这是一个更好的哈希/映射
*/
function makeHash () {
return Object.create(null)
}
var utils = module.exports = {
hash: makeHash,
// global storage for user-registered
// vms, partials and transitions
// 用于用户注册的VM、分区和转换的全局存储
components : makeHash(),
partials : makeHash(),
transitions : makeHash(),
elements : makeHash(),
/**
* get an attribute and remove it.
* 获取一个属性并将其删除。
*/
attr: function (el, type, noRemove) {
var attr = attrs[type],
val = el.getAttribute(attr)
if (!noRemove && val !== null) el.removeAttribute(attr)
return val
},
/**
* Define an ienumerable property
* This avoids it being included in JSON.stringify
* or for...in loops.
*/
defProtected: function (obj, key, val, enumerable, configurable) {
if (obj.hasOwnProperty(key)) return
Object.defineProperty(obj, key, {
value : val,
enumerable : !!enumerable,
configurable : !!configurable
})
},
/**
* Accurate type check
* internal use only, so no need to check for NaN
*/
typeOf: function (obj) {
return toString.call(obj).slice(8, -1)
},
/**
* Most simple bind
* enough for the usecase and fast than native bind()
*/
bind: function (fn, ctx) {
return function (arg) {
return fn.call(ctx, arg)
}
},
/**
* Make sure only strings and numbers are output to html
* 确保只有字符串和数字输出到html
* output empty string is value is not string or number
* 输出空字符串是值不是字符串或数字
*/
toText: function (value) {
/* jshint eqeqeq: false */
return (typeof value === 'string' ||
typeof value === 'boolean' ||
(typeof value === 'number' && value == value)) // deal with NaN
? value
: ''
},
/**
* simple extend
* 简单扩展
*/
extend: function (obj, ext, protective) {
for (var key in ext) {
if (protective && obj[key]) continue
obj[key] = ext[key]
}
},
/**
* filter an array with duplicates into uniques
* 将具有重复项的数组筛选为唯一数组
*/
unique: function (arr) {
var hash = utils.hash(),
i = arr.length,
key, res = []
while (i--) {
key = arr[i]
if (hash[key]) continue
hash[key] = 1
res.push(key)
}
return res
},
/**
* Convert a string template to a dom fragment
* 将字符串模板转换为dom片段
*/
toFragment: function (template) {
if (typeof template !== 'string') {
return template
}
if (template.charAt(0) === '#') {
var templateNode = document.getElementById(template.slice(1))
if (!templateNode) return
template = templateNode.innerHTML
}
var node = document.createElement('div'),
frag = document.createDocumentFragment(),
child
node.innerHTML = template.trim()
/* jshint boss: true */
while (child = node.firstChild) {
frag.appendChild(child)
}
return frag
},
/**
* Convert the object to a ViewModel constructor
* if it is not already one
* 如果对象还不是ViewModel构造函数,请将其转换为ViewModel构造函数
*/
toConstructor: function (obj) {
ViewModel = ViewModel || require('./viewmodel')
return utils.typeOf(obj) === 'Object'
? ViewModel.extend(obj)
: typeof obj === 'function'
? obj
: null
},
isConstructor: function (obj) {
ViewModel = ViewModel || require('./viewmodel')
return obj.prototype instanceof ViewModel || obj === ViewModel
},
/**
* convert certain option values to the desired format.
* 将某些选项值转换为所需格式。
*/
processOptions: function (options) {
var components = options.components,
partials = options.partials,
template = options.template,
elements = options.elements,
key
if (components) {
for (key in components) {
components[key] = utils.toConstructor(components[key])
}
}
if (elements) {
for (key in elements) {
elements[key] = utils.toConstructor(elements[key])
}
}
if (partials) {
for (key in partials) {
partials[key] = utils.toFragment(partials[key])
}
}
if (template) {
options.template = utils.toFragment(template)
}
},
/**
* log for debugging
* 调试日志
*/
log: function () {
if (config.debug && console) {
console.log(join.call(arguments, ' '))
}
},
/**
* warnings, thrown in all cases
* 警告,在所有情况下都会抛出
*/
warn: function() {
if (!config.silent && console) {
console.trace()
console.warn(join.call(arguments, ' '))
}
}
}
源码逐行剖析
extend属性
/**
* simple extend
* 简单扩展
*/
extend: function (obj, ext, protective) {
for (var key in ext) {
if (protective && obj[key]) continue
obj[key] = ext[key]
}
},
var key in ext