vue的源码分析(不断更新中)

4次阅读

共计 3872 个字符,预计需要花费 10 分钟才能阅读完成。

(function (global, factory) {
typeof exports === ‘object’ && typeof module !== ‘undefined’ ? module.exports = factory() :
typeof define === ‘function’ && define.amd ? define(factory) :
(global = global || self, global.Vue = factory());
}(this, function () {‘use strict’;
创建一个自调用匿名函数,设计参数 window,并传入 window 对象。不污染全局变量,也不会别的代码污染
var emptyObject = Object.freeze({});
字面上意义:空对象 = 冻结掉这个对象
Object.freeze({})这个方法核心在于对于这个对象将无法修改,添加。
function isUndef (v) {return v === undefined || v === null}
是否未被定义, 如果参数等于 undefined 或者为空,返回 true
function isDef (v) {return v !== undefined && v !== null}
是否定义, 如果参数不等于 undefined 或者为空,返回 true
function isTrue (v) {return v === true}
是否真,参数为真是返回 true
function isFalse (v) {return v === false}
是否假,参数为真是返回 true
function isPrimitive (value) {
return (
typeof value === ‘string’ ||
typeof value === ‘number’ ||
// $flow-disable-line
typeof value === ‘symbol’ ||
typeof value === ‘boolean’
)
}
是否为原始类型,typeof 返回
function isObject (obj) {return obj !== null && typeof obj === ‘object’}
是否为对象,如果对象不等于空且 typeof 返回为 object,返回 true
var _toString = Object.prototype.toString;
该方法返回描述某个对象数据类型的字符串,如自定义的对象没有被覆盖,则会返回“[object type]”,其中,type 则是实际的对象类型。在使用该方法检测的时候,可以使用 Object.prototype.toString.call()或者 Object.prototype.toString.apply()进行测试,如
function toRawType (value) {return _toString.call(value).slice(8, -1)}
slice(startIndex,endIndex),从 0 开始索引,其中 8 代表从第 8 位(包含)开始截取(本例中代表空格后面的位置),- 1 代表截取到倒数第一位(不含),所以正好截取到 [object String] 中的 String。
function isPlainObject (obj) {return _toString.call(obj) === ‘[object Object]’}
isPlainObject 静态函数 判断指定参数是否是一个纯粹的对象
function isRegExp (v) {return _toString.call(v) === ‘[object RegExp]’}
判断指定参数是否是一个正则
function isValidArrayIndex (val) {
var n = parseFloat(String(val));
return n >= 0 && Math.floor(n) === n && isFinite(val)
}
是否为一个有效的数组,现将值转为字符串,然后用 parseFloat 解析,字符串中的首个字符是否是数字。如果是,则对字符串进行解析,直到到达数字的末端为止,然后以数字返回该数字,而不是作为字符串。如果 n >= 0 以及向下取整等于 n 以及 isFinite 是一个有限数。如 1 /0
function isPromise (val) {
return (
isDef(val) &&
typeof val.then === ‘function’ &&
typeof val.catch === ‘function’
)
}
首先检测这个值是否被定义,然后判断它的 then 和 catch 是否为一个函数
function toString (val) {
return val == null
? ”
: Array.isArray(val) || (isPlainObject(val) && val.toString === _toString)
? JSON.stringify(val, null, 2)
: String(val)
}

首先判断 val 是否为空,如果为空输出 ” 否则 Array.isArray() 先确定是否值为一个 Array 或者前面的 isPlainObject 方法判定是否为一个对象和值转成字符串是否等于 Object.prototype.toString 返回该对象的字符串;如果条件满足 JSON.stringify(val, null, 2)
stringify 是有 3 个参数,

第一个,参数是传入的值可以是 String|Object|String|Number|Boolean|null
第二个,则是过滤器,过滤器可以是数组,也可以是函数
第三个,可以是空的格子 (4) 也可以是特殊符号 /t

否则将 val 转成字符串
function toNumber (val) {
var n = parseFloat(val);
return isNaN(n) ? val : n
}
先使用 parseFloat 函数转换值,然后 isNaN 检查是否为一个数值,如果是输出 val,否则输出 parseFloat(val)基本也就输出 NaN 了
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]; }
}

var isBuiltInTag = makeMap(‘slot,component’, true);
var isReservedAttribute = makeMap(‘key,ref,slot,slot-scope,is’);

官方解释:制作一个映射并返回一个函数,用于检查键是否在该映射中。
创建一个空的对象复制给 map 将值根据‘,’分割成字符串数组遍历循环检测这个数组如果 expectsLowerCase 有值且为 true,将 map 中的数组转换为小写,否则直接输出 map 中的值
实际上主要就是检查 map 中是否存在某个 key 检查标记是否为内置标记检查属性是否为保留属性

function remove (arr, item) {
if (arr.length) {
var index = arr.indexOf(item);
if (index > -1) {
return arr.splice(index, 1)
}
}
}

从数组中移除
indexOf 获取数组中参数的位置如果 index > -1 存在,删除当前.splice(index,howmany,item1,…..,itemX)补充,index 为位置,howmany 为删除数量如果为 0 不删除,这 2 个参数为必填。第三个则是向数组中添加

var hasOwnProperty = Object.prototype.hasOwnProperty;
function hasOwn (obj, key) {
return hasOwnProperty.call(obj, key)
}

这个是很有意思的案例
首先 hasOwnProperty(); 这个方法,它的参数很有意思,字符串或者 Symbol。然后返回 true 或 falseSymbol 是 es6 一种新的类型,所以有的时候问 js 有多少类型啊,记得多了一个。

表示独一无二的值;
声明时不能使用 new Symbol(),而是 Symbol();
声明时可以加参数,用于描述;
作为 key 时不能被遍历;

hasOwn 这个函数主要是检测当前对象是否有某种属性。

这个地方还可以做一些衍生如果你想要实现支持 setter 和 getter 特性的拷贝,该怎么实现?
Object.defineproperties(定义属性)Object.getOwnPropertyDescriptors(es2017,获取对象的多个属性)Object.getOwnPropertyDescriptor(老一点,获取对象的单个属性的属性),但 babel 可以解决。

function cached (fn) {
var cache = Object.create(null);
return (function cachedFn (str) {
var hit = cache[str];
return hit || (cache[str] = fn(str))
})
}

给变量 cache 赋值一个空的对象返回一个 cacheFn 的函数,将函数的参数的 key 带入 cache 并赋值,返回 hit。如果 cache 中存在 str 那么返回 hit,反之将其赋值到 cache 中返回

正文完
 0