【Vue】VUE源码中的一些工具函数

时间:2022-09-26 09:43:45

Vue源码-工具方法

   /*  */
//Object.freeze()阻止修改现有属性的特性和值,并阻止添加新属性。
var emptyObject = Object.freeze({}); // these helpers produces better vm code in JS engines due to their
// explicitness and function inlining
// these helpers produces better vm code in JS engines due to their
// explicitness and function inlining
//判断数据 是否是undefined或者null
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
} /**
* Check if value is primitive
* //判断数据类型是否是string,number,symbol,boolean
*/
function isPrimitive(value) {
//判断数据类型是否是string,number,symbol,boolean
return (
typeof value === 'string' ||
typeof value === 'number' ||
// $flow-disable-line
typeof value === 'symbol' ||
typeof value === 'boolean'
)
} /**
* Quick object check - this is primarily used to tell
* Objects from primitive values when we know the value
* is a JSON-compliant type.
*/
function isObject(obj) {
//判断是否是对象
return obj !== null && typeof obj === 'object'
} /**
* Get the raw type string of a value e.g. [object Object]
*/
//获取toString 简写
var _toString = Object.prototype.toString; function toRawType(value) {
//类型判断 返会Array ,Function,String,Object,Re 等
return _toString.call(value).slice(8, -1)
} /**
* Strict object type check. Only returns true
* for plain JavaScript objects.
*/
function isPlainObject(obj) {
//判断是否是对象
return _toString.call(obj) === '[object Object]'
} function isRegExp(v) {
//判断是否是正则对象
return _toString.call(v) === '[object RegExp]'
} /**
* Check if val is a valid array index.
*/
/**
* Check if val is a valid array index.
* 检查VAL是否是有效的数组索引。
*/
function isValidArrayIndex(val) {
//isFinite 检测是否是数据
//Math.floor 向下取整
var n = parseFloat(String(val));
//isFinite 如果 number 是有限数字(或可转换为有限数字),那么返回 true。否则,如果 number 是 NaN(非数字),或者是正、负无穷大的数,则返回 false。
return n >= 0 && Math.floor(n) === n && isFinite(val)
} /**
* Convert a value to a string that is actually rendered.
*/
function toString(val) { //将对象或者其他基本数据 变成一个 字符串
return val == null
? ''
: typeof val === 'object'
? JSON.stringify(val, null, 2)
: String(val)
} /**
* Convert a input value to a number for persistence.
* If the conversion fails, return original string.
*/
function toNumber(val) {
//字符串转数字,如果失败则返回字符串
var n = parseFloat(val);
return isNaN(n) ? val : n
} /**
* Make a map and return a function for checking if a key
* is in that map.
*
* //map 对象中的[name1,name2,name3,name4] 变成这样的map{name1:true,name2:true,name3:true,name4:true}
* 并且传进一个key值取值,这里用到策略者模式
*/
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; //map 对象中的[name1,name2,name3,name4] 变成这样的map{name1:true,name2:true,name3:true,name4:true}
}
return expectsLowerCase
? function (val) {
return map[val.toLowerCase()];
} //返回一个柯里化函数 toLowerCase转换成小写
: function (val) {
return map[val];
} //返回一个柯里化函数 并且把map中添加一个 属性建
} /**
* Check if a tag is a built-in tag.
* 检查标记是否为内置标记。
*/
var isBuiltInTag = makeMap('slot,component', true); /**
* Check if a attribute is a reserved attribute.
* 检查属性是否为保留属性。
* isReservedAttribute=function(vale){ map{key:true,ref:true,slot-scope:true,is:true,vaule:undefined} }
*/
var isReservedAttribute = makeMap('key,ref,slot,slot-scope,is'); /**
* Remove an item from an array
* //删除数组
*/
function remove(arr, item) {
if (arr.length) {
var index = arr.indexOf(item);
if (index > -1) {
return arr.splice(index, 1)
}
}
} /**
* Check whether the object has the property.
*检查对象属性是否是实例化还是原型上面的
*/
var hasOwnProperty = Object.prototype.hasOwnProperty; function hasOwn(obj, key) {
return hasOwnProperty.call(obj, key)
} /**
* Create a cached version of a pure function.
*/
/**
* Create a cached version of a pure function.
* 创建纯函数的缓存版本。
* 创建一个函数,缓存,再return 返回柯里化函数
* 闭包用法
*/
/***********************************************************************************************
*函数名 :cached
*函数功能描述 : 创建纯函数的缓存版本。 创建一个函数,缓存,再return 返回柯里化函数 闭包用法
*函数参数 : fn 函数
*函数返回值 : fn
*作者 :
*函数创建日期 :
*函数修改日期 :
*修改人 :
*修改原因 :
*版本 :
*历史版本 :
***********************************************************************************************/ /*
* var aFn = cached(function(string){
*
* return string
* })
* aFn(string1);
* aFn(string2);
* aFn(string);
* aFn(string1);
* aFn(string2);
*
* aFn 函数会多次调用 里面就能体现了
* 用对象去缓存记录函数
* */ 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.
* 用连字符分隔的字符串。
* camelize = cachedFn(str)=>{ var hit = cache[str];
return hit || (cache[str] = fn(str))} 调用一个camelize 存一个建进来 调用两次 如果建一样就返回 hit 横线-的转换成驼峰写法
可以让这样的的属性 v-model 变成 vModel
*/
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)
}); /**
* Hyphenate a camelCase string.
* \B的用法
\B是非单词分界符,即可以查出是否包含某个字,如“ABCDEFGHIJK”中是否包含“BCDEFGHIJK”这个字。
*/
var hyphenateRE = /\B([A-Z])/g;
var hyphenate = cached(function (str) {
//大写字母,加完减号又转成小写了 比如把驼峰 aBc 变成了 a-bc
//匹配大写字母并且两面不是空白的 替换成 '-' + '字母' 在全部转换成小写
return str.replace(hyphenateRE, '-$1').toLowerCase();
}); /**
* Simple bind polyfill for environments that do not support it... e.g.
* PhantomJS 1.x. Technically we don't need this anymore since native bind is
* now more performant in most browsers, but removing it would be breaking for
* code that was able to run in PhantomJS 1.x, so this must be kept for
* backwards compatibility.
* 改变this 上下文
* 执行方式
*/ /* istanbul ignore next */
//绑定事件 并且改变上下文指向
function polyfillBind(fn, ctx) {
function boundFn(a) {
var l = arguments.length;
return l
? l > 1
? fn.apply(ctx, arguments)
: fn.call(ctx, a)
: fn.call(ctx)
} boundFn._length = fn.length;
return boundFn
} //执行方式
function nativeBind(fn, ctx) {
return fn.bind(ctx)
} //bing 改变this上下文
var bind = Function.prototype.bind
? nativeBind
: polyfillBind; /**
* 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.
* * 浅拷贝
*/
/***********************************************************************************************
*函数名 :extend
*函数功能描述 : 浅拷贝
*函数参数 : to 超类, _from 子类
*函数返回值 : 合并类
*作者 :
*函数创建日期 :
*函数修改日期 :
*修改人 :
*修改原因 :
*版本 :
*历史版本 :
***********************************************************************************************/
//对象浅拷贝,参数(to, _from)循环_from的值,会覆盖掉to的值
function extend(to, _from) {
for (var key in _from) {
to[key] = _from[key];
}
return to
} /**
* Merge an Array of Objects into a single Object.
*
*/
/***********************************************************************************************
*函数名 :toObject
*函数功能描述 : 和并对象数组合并成一个对象
*函数参数 : arr 数组对象类
*函数返回值 :
*作者 :
*函数创建日期 :
*函数修改日期 :
*修改人 :
*修改原因 :
*版本 :
*历史版本 :
***********************************************************************************************/ function toObject(arr) {
var res = {};
for (var i = 0; i < arr.length; i++) {
if (arr[i]) {
extend(res, arr[i]);
}
}
return res
} /**
* Perform no operation.
* Stubbing args to make Flow happy without leaving useless transpiled code
* with ...rest (https://flow.org/blog/2017/05/07/Strict-Function-Call-Arity/) */
function noop(a, b, c) {
} /**
* Always return false.
* 返回假的
*/
var no = function (a, b, c) {
return false;
}; /**
* Return same value
*返回相同值
*/
var identity = function (_) {
return _;
}; /**
* Generate a static keys string from compiler modules.
*
* [{ staticKeys:1},{staticKeys:2},{staticKeys:3}]
* 连接数组对象中的 staticKeys key值,连接成一个字符串 str=‘1,2,3’
*/
function genStaticKeys(modules) {
return modules.reduce(
function (keys, m) {
//累加staticKeys的值变成数组
return keys.concat(m.staticKeys || [])
},
[]
).join(',') //转换成字符串
} /**
* Check if two values are loosely equal - that is,
* if they are plain objects, do they have the same shape?
* 检测a和b的数据类型,是否是不是数组或者对象,对象的key长度一样即可,数组长度一样即可
*/
function looseEqual(a, b) {
if (a === b) {
return true
} //如果a和b是完全相等 则true
var isObjectA = isObject(a);
var isObjectB = isObject(b);
if (isObjectA && isObjectB) { //如果a和都是对象则让下走
try {
var isArrayA = Array.isArray(a);
var isArrayB = Array.isArray(b);
if (isArrayA && isArrayB) { //如果a和b都是数组
// every 条件判断
return a.length === b.length && a.every(function (e, i) { //如果a长度和b长度一样的时候
return looseEqual(e, b[i]) //递归
})
} else if (!isArrayA && !isArrayB) { //或者a和b都不是数组
var keysA = Object.keys(a); // 获取到a的key值 变成一个数组
var keysB = Object.keys(b); // 获取到b的key值 变成一个数组
//他们的对象key值长度是一样的时候 则加载every 条件函数
return keysA.length === keysB.length && keysA.every(function (key) {
//递归 a和b的值
return looseEqual(a[key], b[key])
})
} else {
//如果不是对象跳槽循环
/* istanbul ignore next */
return false
}
} catch (e) {
//如果不是对象跳槽循环
/* istanbul ignore next */
return false
}
} else if (!isObjectA && !isObjectB) { //b和a 都不是对象的时候
//把a和b变成字符串,判断他们是否相同
return String(a) === String(b)
} else {
return false
}
} // 判断 arr数组中的数组 是否和val相等。
// 或者 arr数组中的对象,或者对象数组 是否和val 相等
function looseIndexOf(arr, val) {
for (var i = 0; i < arr.length; i++) {
if (looseEqual(arr[i], val)) {
return i
}
}
return -1
} /**
* Ensure a function is called only once.
* 确保该函数只调用一次 闭包函数
*/
function once(fn) {
var called = false;
return function () {
if (!called) {
called = true;
fn.apply(this, arguments);
}
}
}

【Vue】VUE源码中的一些工具函数的更多相关文章

  1. Vue&period;js源码中大量采用的ES6新特性介绍:模块、let、const

    1 关于ES6      ECMAScript6(以下简称ES6)是JavaScript语言的最新一代标准,发布于2015年6月,因为ECMA委员会决定从ES6起每年更新一次标准,因此ES6被改名为E ...

  2. jQuery源码分析-03扩展工具函数jQuery&period;extend

    // 扩展工具函数 jQuery.extend({ // http://www.w3school.com.cn/jquery/core_noconflict.asp // 释放$的 jQuery 控制 ...

  3. 解读Vue&period;use&lpar;&rpar;源码

    Vue.use() vue.use()的作用: 官方文档的解释: 安装 Vue.js 插件.如果插件是一个对象,必须提供 install 方法.如果插件是一个函数,它会被作为 install 方法.i ...

  4. 从template到DOM&lpar;Vue&period;js源码角度看内部运行机制&rpar;

    写在前面 这篇文章算是对最近写的一系列Vue.js源码的文章(https://github.com/answershuto/learnVue)的总结吧,在阅读源码的过程中也确实受益匪浅,希望自己的这些 ...

  5. vue&period;js使用webpack发布,部署到服务器上之后在浏览器中可以查看到vue文件源码

    webpack+vue 2.0打包发布之后,将发布的文件部署到服务器中之后,浏览器中访问的时候会出现一个webpack文件夹,里边会显示vue文件源码 如果不想让vue源文件显示出来,可以在confi ...

  6. 挖掘隐藏在源码中的Vue技巧!

    前言 最近关于Vue的技巧文章大热,我自己也写过一篇(vue开发中的"骚操作"),但这篇文章的技巧是能在Vue的文档中找到蛛丝马迹的,而有些文章说的技巧在Vue文档中根本找不到踪迹 ...

  7. 2018-11-23 手工翻译Vue&period;js源码&colon;尝试重命名标识符与文本

    续前文: 手工翻译Vue.js源码第一步:14个文件重命名 对core/instance/索引中的变量, 方法进行重命名如下(题图): import { 混入初始化 } from './初始化' im ...

  8. 2018-11-21 手工翻译Vue&period;js源码第一步&colon;14个文件重命名

    背景 对现有开源项目的代码进行翻译(文件名/命名/注释) · Issue #107 · program-in-chinese/overview 简单地说, 通过翻译源码, 提高项目代码可读性(对于母语 ...

  9. Vue&period;js 源码分析&lpar;二十八&rpar; 高级应用 transition组件 详解

    transition组件可以给任何元素和组件添加进入/离开过渡,但只能给单个组件实行过渡效果(多个元素可以用transition-group组件,下一节再讲),调用该内置组件时,可以传入如下特性: n ...

随机推荐

  1. AngularJS常用插件与指令收集

    angularjs 组件列表 bindonce UI-Router Angular Tree angular-ngSanitize模块-$sanitize服务详解 使用 AngularJS 开发一个大 ...

  2. Android studio 菜单介绍 3&period;1&period;文件&lpar;File&rpar;

    文件(File) 3.1.1.New 1. Android Studio中的Project相当于Eclipse中的Workspace 3.1.5.Close Prject 关闭当前项目打开的窗口 2. ...

  3. Windows Server 2008配置服务器证书&lbrack;转载&rsqb;

    备忘 http://wangchunhai.blog.51cto.com/225186/139451

  4. linux 学习5 文本编辑器 vim

    vim 没有菜单,只有命令 //root用户既可以用vi,也可以用vim, 无实质性区别,vim是vi的升级版//粘贴用shift+insert , 要在insert模式下粘贴,否则粘贴不全// ^ ...

  5. 关于CSS3线型渐变这些事儿

    CSS3兼容各浏览器的线型渐变方法: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" &quot ...

  6. 20145211 《Java程序设计》第8周学习总结——自在飞花轻似梦

    教材学习内容总结 认识NIO Java NIO(New Input/Output)--新的输入/输出API包--是2002年引入到J2SE 1.4里的.Java NIO的目标是提高Java平台上的I/ ...

  7. Wireshark抓包工具使用教程以及常用抓包规则

    转载:http://fangxin.blog.51cto.com/1125131/735178 Wireshark是一个非常好用的抓包工具,当我们遇到一些和网络相关的问题时,可以通过这个工具进行分析, ...

  8. javascript 之闭包-理解不了来找我

    1,闭包是什么 (百度百科定义)--闭包是可以包含*(未绑定到特定对象)变量的代码块:这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义(局部变 量).“闭包” 一词 ...

  9. ArrayList源码浅析(jdk1&period;8)

    ArrayList的实质就是动态数组.所以可以通过下标准确的找到目标元素,因此查找的效率高.但是添加或删除元素会涉及到大量元素的位置移动,所以效率低. 一.构造方法 ArrayList提供了3个构造方 ...

  10. mysql中data和datatime的区别

    1.显示格式的区别 Date显示格式:YYYY-MM-DD:DateTime显示格式:YYYY-MM-DD HH:mm:ss. 2.显示范围的区别 Date显示范围是1601-01-01 到 9999 ...