以前用过不到一年的react,后来vue开始流行,看了一些,感觉和react差不多,没深入研究过,最近没什么事,继续读vue的源码,顺便记个笔记,因为听说我记性不太好。。。
另外就是源码里有很多写的很好的函数,很巧妙,很值得学习借鉴下
正题
1. 这段代码好多库的开头里都有,兼容性用的,多层嵌套的匿名函数与执行。
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global.Vue = factory());
}(this, (function () {
//---
})));
2. 在上面代码的下面是好多很简洁的函数
函数很简洁,很简单,无需赘述,正常人都能一眼看明白。记录几个有用的。
1)用于判断object类型值得具体类型,同理的还有判断Array
var toString = Object.prototype.toString;
function isPlainObject (obj) {
return toString.call(obj) === '[object Object]'
}
function isRegExp (v) {
return toString.call(v) === '[object RegExp]'
}
2)_toString这个函数没有什么特别的,但是引起注意的是JSON.stringify,这个函数用过很多次,但是我都是只用一个参数,这里居然用三个参数,还有这种用法?网上查询后得知,这个2其实就是缩进2个空格,null就是没有做替换,详见JSON.stringify详解
function _toString (val) {
return val == null
? ''
: typeof val === 'object'
? JSON.stringify(val, null, 2)
: String(val)
}
3) 这个makeMap函数乍一看有点高大上,其实就是一个字典。。。
对传入的以逗号分隔的str字符串先转成数组list,然后做成map的字典,以这个数组list的值为key,value为true,生成字典map,最后判断下expectsLowerCase为true,则以小写返回字典,否则原样返回字典。
我注意到的是Line86的var map = Object.create(null);这种定义方法,查询了些资料,简单总结了下http://blog.csdn.net/fangfanggaogao/article/details/72642588
function makeMap (
str,
expectsLowerCase
) {
var map = Object.create(null);
var list = str.split(',');
for (var i = 0; i < list.length; i++) {
map[list[i]] = true;
}
return expectsLowerCase
? function (val) { return map[val.toLowerCase()]; }
: function (val) { return map[val]; }
}
4)至于remove函数,虽然看起来很简单,但是我以前居然不知道这种简单的写法,都是先找到指定元素的索引,然后把后面值往前面推进或者是把索引前后的数组再单独拿出来合并的。。。
看到这个后,觉得以前好傻。。。
function remove (arr, item) {
if (arr.length) {
var index = arr.indexOf(item);
if (index > -1) {
return arr.splice(index, 1)
}
}
}
是的,我一直以为indexOf只是用于字符串中的查找元素索引值,原来也可以用于数组中,get到了。
而splice() 则是可以向/从数组中添加/删除项目,然后返回被删除的项目。这里是splice的详细用法
arrayObject.splice(index,howmany,item1,.....,itemX)
参数 | 描述 |
---|---|
index | 必需。整数,规定添加/删除项目的位置,使用负数可从数组结尾处规定位置。 |
howmany | 必需。要删除的项目数量。如果设置为 0,则不会删除项目。 |
item1, ..., itemX | 可选。向数组添加的新项目。 |
5) 这里定义了一个纯函数(pure function)cached,纯函数就是不因外界或者传值影响而改变的结果值得函数,如sin和cos这些数学函数,而random()是非纯函数,因为每次调用潜在地产生不同的值则不是纯函数, 纯函数参考地址
但是不懂这里为什么要定义cached这个函数,因为不用cached也是可以得,暂留疑问
/**
* Create a cached version of a pure function.
*/
function cached (fn) {
var cache = Object.create(null);
return (function cachedFn (str) {
var hit = cache[str];
return hit || (cache[str] = fn(str))
})
}
/**
* Camelize a hyphen-delimited string.
*/
var camelizeRE = /-(\w)/g;
var camelize = cached(function (str) {
return str.replace(camelizeRE, function (_, c) { return c ? c.toUpperCase() : ''; })
});
/**
* Capitalize a string.
*/
var capitalize = cached(function (str) {
return str.charAt(0).toUpperCase() + str.slice(1)
});
6) 放了一个月,继续再写一些,从这里Line239:looseEqual里看到看到String,查了下与toString的区别,这里写的很详细,简言之就是toString可以转化进制,比如说a=17,a.toString(16)的结果就是字符串的11,但是toString不能转换null和undefined,会报错。String不能定义进制,就是完全平移的转换为字符串。looseEqual
检查object的时候,
var a = {
aa: 1,
bb: 2
},
b = {
bb: 2,
aa: 1
};
这里的a和b是不相等的。