vlambda博客
学习文章列表

vue2.6.11源码深度解析(一)

琵琶语 - 林海 From 前端大全之Node.js 04:13

vue2.6.11源码深度解析(一)

//1.导出不同格式的js(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';

vue2.6.11源码深度解析(一)

//2.创建一个不可修改的对象 var emptyObject = Object.freeze({});

vue2.6.11源码深度解析(一)

//3. 6个isXXX名称的函数:这几个函数是用来各司其职的检查数据类型的 //第一.检查一个值是不是没有定义,这里检查了它是undefined或者null类型,满足其一就表示它已定义,返回true。 function isUndef (v) { return v === undefined || v === null }//第二.检查一个值是不是定义了,必须同时满足它不是undefined类型且不是null类型。 function isDef (v) { return v !== undefined && v !== null }//第三.检查一个值是不是true function isTrue (v) { return v === true }//第四.检查一个值是不是false function isFalse (v) { return v === false }
/** *第五.检查值是否为基础数据类型 */ function isPrimitive (value) { return ( typeof value === 'string' || typeof value === 'number' || typeof value === 'symbol' || typeof value === 'boolean' ) }
/** * 拓展: 为什么要检查一下obj !== null呢?因为虽然在js中Null与Object是两种数据类型,但是 typeof null 和 typeof {} 的结果是一样的, 所以这里要先排除null值的干扰 */ //第六:检查是对象,但不是null 因为:typeof null 控制台运行的结果是"object" function isObject (obj) { return obj !== null && typeof obj === 'object' }


vue2.6.11源码深度解析(一)

//4.获取一个值的原始类型字符串 e.g., [object Object],截取后,返回类型值,如 "Number", "Boolean", "Array"等 /** * Get the raw type string of a value, e.g., [object Object]. * 作用: 获取一个值的原始类型字符串 * Object.prototype.toString.call(1) 控制台运行结果:"[object Number]" Object.prototype.toString.call([]) 控制台运行结果:"[object Array]" Object.prototype.toString.call(1).slice(8, -1) 控制台运行结果:"Number" Object.prototype.toString.call([]).slice(8, -1)控制台运行结果:"Array" 拓展: prototype 属性使您有能力向对象添加属性和方法。eg: object.prototype.name=value */ var _toString = Object.prototype.toString;
function toRawType (value) { return _toString.call(value).slice(8, -1) }



//5.严格的类型检查,判断是不是对象 /** * Strict object type check. Only returns true for plain JavaScript objects * 拓展: 为什么特意加一句 Only returns true for plain JavaScript objects.呢?因为有一些值,虽然也属于js中的对象,但是有着更精确的数据类型,比如: Object.prototype.toString.call([]) // "[object Array]" Object.prototype.toString.call(()=>{}) // "[object Function]" Object.prototype.toString.call(null) // "[object Null]" ... plain 平的;简单的;朴素的;清晰的 */ function isPlainObject (obj) { return _toString.call(obj) === '[object Object]' }


vue2.6.11源码深度解析(一)

//6.作用: 检查一个值是不是正则表达式。 /* 拓展: 正则表达式不是对象吗?为什么不能直接使用typeof操作符检查呢? 这主要是处于兼容不同浏览器的考虑: typeof /s/ === 'function'; // Chrome 1-12 Non-conform to ECMAScript 5.1 typeof /s/ === 'object'; // Firefox 5+ Conform to ECMAScript 5.1 */ function isRegExp (v) { return _toString.call(v) === '[object RegExp]' }

vue2.6.11源码深度解析(一)

//7.作用: 检查一个值是不是有效的数组索引,要满足:非负数, 整数, 有限大 /** * Check if val is a valid array index. * 拓展: 这主要是检查外来的值作为数组的索引的情况。 * isFinite(number) 函数用于检查其参数是否是无穷大。number 必需。要检测的数字。返回值 :如果 number 是有限数字(或可转换为有限数字),那么返回 true。否则,如果 number 是 NaN(非数字),或者是正、负无穷大的数,则返回 false。 * 解释:调用 String(val) 时,它只把 val 转换成原始的字符串,并返回转换后的值。 */ function isValidArrayIndex (val) { var n = parseFloat(String(val)); return n >= 0 && Math.floor(n) === n && isFinite(val) }

vue2.6.11源码深度解析(一)


//8.判断是否是一个 Promise 对象 function isPromise (val) { return ( isDef(val) && typeof val.then === 'function' && typeof val.catch === 'function' ) }


vue2.6.11源码深度解析(一)

 //9.作用: 把一个值转换成可以渲染的字符串 /** * Convert a value to a string that is actually rendered. //单词 :convert 转换 rendered渲染 * 拓展: 第一个判断用的是 == 而不是 ===, 所以当值为undefined或者null时都会返回空串 解释:JSON.stringify() 方法将 JavaScript 对象 或者 数组 转换为字符串。 JSON.stringify接收三个参数,分别是要序列化的值, 要序列化的属性, 序列化所需的空格 解释:isPlainObject方法判定是否为一个对象 和val.toString值转成字符串是否等于Object.prototype.toString返回该对象的字符串; : String(val)否则将val转成字符串 */ //作用: 把一个值转换成可以渲染的字符串 function toString (val) { return val == null ? '' : Array.isArray(val) || (isPlainObject(val) && val.toString === _toString) ? JSON.stringify(val, null, 2) : String(val) }


vue2.6.11源码深度解析(一)

//10.作用: 把一个值转换成数字,转化成功,返回数字,否则原样返回。 /** * Convert an input value to a number for persistence. * If the conversion fails, return original string. * 解释:isNaN() 函数用于检查其参数是否是非数字值。如果参数值为 NaN 或字符串、对象、undefined等非数字值则返回 true, 否则返回 false。 */ function toNumber (val) { var n = parseFloat(val); return isNaN(n) ? val : n }


vue2.6.11源码深度解析(一)

//11.作用: 生成一个map,返回一个函数来检查一个键是不是在这个map中。 /** * Make a map and return a function for checking if a key is in that map. * 如果需要小写(expectsLowerCase = true)的话,就将 val 的值转换成小写再检查;否则直接检查 这里的检查,就是检查传入的 val(键), 是不是在map中,在的话会根据该键名,找到对应的值(true) 这里返回的是一个函数,该函数接收一个待检查的键名称,返回查找结果(true/undefined) */ function makeMap ( str, expectsLowerCase ) { var map = Object.create(null); var list = str.split(',');//将str 按 , 分割成字符串,组成新数组list for (var i = 0; i < list.length; i++) { map[list[i]] = true; }//console.log(map);//如果 str = 'hello, world', 那么这个循环后{hello: true, " world": true} return expectsLowerCase ? function (val) { return map[val.toLowerCase()]; } : function (val) { return map[val]; } }
/** * Check if a tag is a built-in tag.作用: 检查一个标签是不是vue的内置标签 */ var isBuiltInTag = makeMap('slot,component', true);//slot 位置;狭槽;水沟;硬币投币口
/** * 检查一个属性是不是vue的保留属性 */ var isReservedAttribute = makeMap('key,ref,slot,slot-scope,is');//scope 范围;余地;视野;眼界;导弹射程 ref 参考 。 reserved保留 预订(座位等);储备;拥有(某种权利);留出(一部分稍后使用);用于(特定场合);暂不作(判断或决定);把……专门留给;n. 储备(量);自然保护区;居住地;预备队;预备役部队;缄默;保留意见;储备金;(拍卖中的)底价;(印染中的)防染本色区



vue2.6.11源码深度解析(一)


//12作用: 移除数组的某一项。 function remove (arr, item) { if (arr.length) { var index = arr.indexOf(item);//找到这一项在数组arr中的下标位置,找不到返回-1;eg: [12,23,45,46,465,555].indexOf(45) ==>2 ;[12,23,45,46,465,555].indexOf(2) ==>-1 if (index > -1) {//找到了 return arr.splice(index, 1)//eg: [12,23,45,46,465,555].splice(2,1) ==》[45] 返回移除后的这一项 } } }



//13.作用: 检查一个对象是否包含某属性 /** * Check whether an object has the property. * 拓展: 这里要思考的是,为什么不直接调用对象上的hasOwnProperty方法,反而要找对象原型上的呢?原因其实很简单,因为对象上的hasOwnProperty是可以被改写的,万一被重写了方法就无法实现这种检查了 */ var hasOwnProperty = Object.prototype.hasOwnProperty; function hasOwn (obj, key) { return hasOwnProperty.call(obj, key) }



vue2.6.11源码深度解析(一)

//14.作用: 为一个纯函数创建一个缓存的版本。 /** * Create a cached version of a pure function. * 解析: 因为一个纯函数的返回值只跟它的参数有关,所以我们可以将入参作为key,返回值作为value缓存成key-value的键值对,这样如果之后还想获取之前同样参数的计算结果时,不需要再重新计算了,直接获取之前计算过的结果就行。 * 拓展: 纯函数:一个函数的返回结果只依赖于它的参数,并且在执行过程里面没有副作用,则该函数可以称为纯函数。 解释:缓存的数据处理,只有当缓存中没有时才经过函数处理。 function cached(fn) { var cache = Object.create(null); return ( function cachedFn(str) { var hit = cache[str]; console.log(cache);//{Frank: "Frank", Kai: "Kai"} console.log(cache["Frank"]);//Frank return hit || (cache[str] = fn(str)) } ) } var capitalize = cached(function (str) { return str.charAt(0).toUpperCase() + str.slice(1) }); //未缓存 var lastName = capitalize("Frank") var firstName = capitalize("Kai") //已缓存 var secondName = capitalize("Kai") 建议采用Chrome控制台的开发面板进行测试,6个变量命名处打断点,采用F10的形式,去查看每个变量命名时的完整调用过程,对比未缓存和已缓存处的call stack,就会立刻理解函数缓存的原理。 */ function cached (fn) {//cached函数传一个参数fn方法,fn方法参数返回一个计算后的字符串 var cache = Object.create(null);//创建一个空对象cache return (function cachedFn (str) {//返回一个闭包函数cachedFn,该函数的参数str是要处理的原字符串 var hit = cache[str];//定义一个变量hit保存cache[str] return hit || (cache[str] = fn(str))//变量hit如果有对应的值,则直接返回,不再需要通过外层cached方法传递进来的fn方法的计算,反之,则需要计算后赋值给cache[str]同时返回。 }) }


vue2.6.11源码深度解析(一)

//15.作用: 将连字符-连接的字符串转化成驼峰标识的字符串 /** * Camelize a hyphen-delimited string. * 解析: 可以通过此例来感受下上面的cached函数的作用,因为cache的参数, 一个转换连字符字符串的函数,是一个很纯很纯的函数,所以可以把它缓存起来。 * 使用: camelize('hello-world') // 'helloWorld' * 替换关键词: 2种: 1. 简单替换: 将所有关键词,替换为相同的新值 str=str.replace(/正则/g,"新词") 2. 高级替换: 根据每个关键词的不同,动态生成新值替换ss str=str.replace(/正则/g,function(kword){ return 根据kword的不同,返回不同新值 }); //return的结果会替换到当前kword所在位置 原理: 每发现一个关键词,就自动执行一次function 执行时,自动将本次找到的关键词,传给参数kword 函数的本质: 函数名其实时一个普通变量 函数其实是一个保存一段代码的对象 什么是: 封装一段代码段的对象 何时使用函数: 只要一段代码可能被重用! 如何: 3种: 1. 声明: function 函数名(参数列表){ 函数体; return 返回值 } 问题: 会被声明提前 声明提前(hoist): 程序开始执行前,引擎会将var声明的变量和function声明的函数提前到当前作用域的顶部。赋值留在原地。 解决: 2. 用赋值方式: var函数名=function (参数列表){ 函数体; return 返回值 } 优点: 不会被声明提前 揭示: 函数其实也是一个对象,函数名其实只是一个普通的变量。 3. 用new:-----了解 var 函数名= new Function("参数","参数",…,"函数体;return 返回值") */ var camelizeRE = /-(\w)/g;// \w : 一位字母数字或下划线: \w [0-9A-Za-z_] var camelize = cached(function (str) { return str.replace(camelizeRE, function (_, c) { return c ? c.toUpperCase() : ''; }) });


vue2.6.11源码深度解析(一)



//16.作用: 将一个字符串的首字母大写后返回,也是可以被缓存的函数。 /** * Capitalize a string. * 将一个字符串的首字母大写后返回 * 使用:capitalize('hello') // 'Hello' * charAt() 方法用于返回指定索引处的字符。索引范围为从 0 到 length() - 1。 */ var capitalize = cached(function (str) { return str.charAt(0).toUpperCase() + str.slice(1) });

vue2.6.11源码深度解析(一)


想知更多解析,请等下回分解!谢谢

vue2.6.11源码深度解析(一)


前端大全之Nodejs:免费分享前端技术文章,不定时前端干货发送


欢迎长按(扫描)二维码关注:前端大全之Nodejs



vue2.6.11源码深度解析(一)

长按二维码

vue2.6.11源码深度解析(一)
vue2.6.11源码深度解析(一)

vue2.6.11源码深度解析(一) vue2.6.11源码深度解析(一) vue2.6.11源码深度解析(一) vue2.6.11源码深度解析(一) vue2.6.11源码深度解析(一) vue2.6.11源码深度解析(一) vue2.6.11源码深度解析(一) vue2.6.11源码深度解析(一)

vue2.6.11源码深度解析(一) vue2.6.11源码深度解析(一) vue2.6.11源码深度解析(一) vue2.6.11源码深度解析(一) vue2.6.11源码深度解析(一) vue2.6.11源码深度解析(一) vue2.6.11源码深度解析(一)