vue源码分析1
2018-09-05 本文已影响0人
小强不是蟑螂啊
Vue.js v2 .5 .13, 大概一万行, 现在逐行分析下。 大概20 - 30 篇吧, 所以每次应该300 - 500 行, 坚持就是胜利啊。
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global.Vue = factory());
}(this, (function () {
'use strict';
// commond.js 规范: moudle.exports
// requrei.js 规范:define()
// 如果都不支持 就绑定到引入的顶级对象上的vue属性,现在框架基本上都是这个样子。
// 未定义
function isUndef(v) {
return v === undefined || v === null
}
// 已定义
function isDef(v) {
return v !== undefined && v !== null
}
// 是否为真
function isTrue(v) {
return v === true
}
// 是否为假
function isFalse(v) {
return v === false
}
//判断是否为基本数据 string number symbol boolean
function isPrimitive(value) {
return (
typeof value === 'string' ||
typeof value === 'number' ||
// $flow-disable-line
typeof value === 'symbol' ||
typeof value === 'boolean'
)
}
function isObject(obj) {
return obj !== null && typeof obj === 'object' // 是否是个对象,typeof是对象同时又不是Null即可
}
/**
* Get the raw type string of a value e.g. [object Object]
*/
var _toString = Object.prototype.toString;
function toRawType(value) {
return _toString.call(value).slice(8, -1) // 调用Object.prototype.toString,返回的数据类型数组的第二个元素的
}
// 判断是否是一个原始对象
function isPlainObject(obj) {
return _toString.call(obj) === '[object Object]'
}
function isRegExp(v) {
return _toString.call(v) === '[object RegExp]'
}
// 是否是一个数组的key
function isValidArrayIndex(val) {
var n = parseFloat(String(val));
return n >= 0 && Math.floor(n) === n && isFinite(val)
}
// 转换为字符串
function toString(val) {
return val == null ?
'' :
typeof val === 'object' ?
JSON.stringify(val, null, 2) :
String(val)
}
//转化为数字
function toNumber(val) {
var n = parseFloat(val);
return isNaN(n) ? val : n
}
// 传入一个以逗号为分割的字符串,切分成数组,检测返回的函数中是否有这个值,第二个参数定义是否化为小写,起到缓存的作用
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];
}
}
// 是否有slot,component这两个标签
var isBuiltInTag = makeMap('slot,component', true);
// 是否有key,ref,slot,slot-scope,is这几个属性
var isReservedAttribute = makeMap('key,ref,slot,slot-scope,is');
var camelizeRE = /-(\w)/g;
var camelize = cached(function (str) {
return str.replace(camelizeRE, function (_, c) {
return c ? c.toUpperCase() : '';
}) //replace的第二个函数参数是正则匹配的数组各个参数
});
/**
* Capitalize a string.
*/
var capitalize = cached(function (str) {
return str.charAt(0).toUpperCase() + str.slice(1)
});
// 以上是两种有中间线链接的字符串转化为驼峰写法
/**
* Hyphenate a camelCase string.
*/
var hyphenateRE = /\B([A-Z])/g;
var hyphenate = cached(function (str) {
return str.replace(hyphenateRE, '-$1').toLowerCase()
});
// 将字符串中间的空格转化为-$1符号
/**
* Simple bind, faster than native
*/
function bind(fn, ctx) {
function boundFn(a) {
var l = arguments.length;
return l ?
l > 1 ?
fn.apply(ctx, arguments) :
fn.call(ctx, a) :
fn.call(ctx)
}
// record original fn length
boundFn._length = fn.length;
return boundFn
}
// 函数绑定,按照 参数的数量分为call和apply绑定,如果没有参数,就用ctx作为参数,记录下_length为传入函数的参数数量
/**
* Convert an Array-like object to a real Array.
*/
function toArray(list, start) {
start = start || 0;
var i = list.length - start;
var ret = new Array(i);
while (i--) {
ret[i] = list[i + start];
}
return ret
}
// 取数组得到某个值以后的数组,返回一个新数组
/**
* Mix properties into target object.
*/
function extend(to, _from) {
for (var key in _from) {
to[key] = _from[key];
}
return to
}
// 将原对象或数组复制到新对象或另一个对象上
function toObject(arr) {
var res = {};
for (var i = 0; i < arr.length; i++) {
if (arr[i]) {
extend(res, arr[i]);
}
}
return res
}
// 输入转为对象
今天十点了, 大概200行, 今天有点少, 下一遍应该多些