已经使用vue很久了,今天打开vue源码,想学习一下。废话不多说,学起来就对啦!😄
源码刚开始是全局的工具函数,接下来看一下这些工具函数的作用和实现!小白学习,大神们请多多指教!
var emptyObject = Object.freeze({});
看到这段代码,发现freeze()这个函数我一直没用过,这个方法名中文的意思是冻结,难道是一个冰封的对象?
这个对象里面所有的方法和属性都被冻结?
然后我就去查阅了文档,果然是一个有意思的方法,和我猜测的差不多。
功能:一个被冻结的对象再也不能被修改;冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。此外,冻结一个对象后该对象的原型也不能被修改。freeze() 返回和传入的参数相同的对象。
function isUndef (v) {
return v === undefined || v === null
}
这个函数就很容易理解了,校验是否为undefined Or null,返回值是true/false;
function isDef (v) {
return v !== undefined && v !== null
}
校验是否不为undefined Or null,返回值是true/false;这个函数和上面的作用正好是相反!
function isTrue (v) {
return v === true
}
检查一个值是不是true,在js里大概有几种为false,往下看👇
isTrue(undefined);//false
isTrue(null);//false
isTrue(false);//false
isTrue(0);//false
isTrue(NaN);//false
isTrue('')//false
顺便复习了一下,这种感觉还不错哟!
function isFalse (v) {
return v === false
}
校验是否是false,返回值是true/false;和上面的函数也是相对应的。
function isPrimitive (value) {
return (
typeof value === 'string' ||
typeof value === 'number' ||
// $flow-disable-line
typeof value === 'symbol' ||
typeof value === 'boolean'
)
}
检查值是否是自带的 基本类型,js基本数据类型我来复习一下哈!字符串/数字/symbol/布尔。
在ES5的时候,我们认知的数据类型确实是 6种:Number、String、Boolean、undefined、object、Null。
ES6 中新增了一种 Symbol 。这种类型的对象永不相等,即始创建的时候传入相同的值,可以解决属性名冲突的问题,做为标记。
谷歌67版本中还出现了一种 bigInt。是指安全存储、操作大整数。(但是很多人不把这个做为一个类型)。
function isObject (obj) {
return obj !== null && typeof obj === 'object'
}
检查是否是一个引用数据,说白了应该是不是一个对象吧!
var _toString = Object.prototype.toString;
// console.log(_toString);[Function: toString]
接下来验证这个方法的时刻到了,往下看⬇️
/*返回数据类型:object*/
_toString.call({}) [object Object]
_toString.call([]) [object Array]
_toString.call("name") [object String]
_toString.call(null) [object Null]
_toString.call(false/true) [object Boolean]
_toString.call(undefined) [object Undefined]
_toString.call(function () {}) [object Function]
_toString.call(new Date()) [object Date]
_toString.call(/[1-9][0-9]*/) [object RegExp]
强迫症的我感觉对齐才舒服呢!😄😄😄
function toRawType (value) {
return _toString.call(value).slice(8, -1)
}
toRawType函数就是把上面返回的值做个截取,例如: [object Number]这个字符串做了截取,得到的结果是"Number".
function isPlainObject (obj) {
return _toString.call(obj) === '[object Object]'
}
toRawType这个函数的作用理解了,这个函数就不难理解,返回值 :ture/false;
function isRegExp (v) {
return _toString.call(v) === '[object RegExp]'
}
检查一个值是不是正则表达式,返回值:true/false;
大家都知道判断数据类型的方法有很多。我们常用的有typeof但是,这个方法有一定的局限性。
typeof null
// "object"
typeof [8]
// "object"
typeof {}
// "object"
typeof function(){}
// "function"
typeof 2
//"number"
typeof ""
//"string"
typeof true
//"boolean"
typeof undefined
//"undefined"
typeof Symbol(2)
//"Symbol"
typeof 无法区分null 数组和对象,通常我们会区分判断Array和Object,,所以为了兼容到所有数据类型,就使用toString.call(v);
这个方法我也很少用的,感觉还是要多写写原生js,吼吼!
function isValidArrayIndex (val) {
var n = parseFloat(String(val));
return n >= 0 && Math.floor(n) === n && isFinite(val)
}
检查val是否是有效的数组索引, isFinite() 函数用于检查其参数是否是无穷大,也可以理解为是否为一个有限数值(finite number)。
如果参数是 NaN,正无穷大或者负无穷大,会返回 false,其他返回 true。好吧,我又孤陋寡闻了,isFinite()这个函数我没有见过。又学习啦!
function isPromise (val) {
return (
isDef(val) &&
typeof val.then === 'function' &&
typeof val.catch === 'function'
)
}
检查是否是一个可使用的Promise对象,这个对象应该是目前使用率蛮高的。例如:console.log(isPromise(new Promise(function (resolve, reject) { })));
function toString (val) {
return val == null
? ''
: Array.isArray(val) || (isPlainObject(val) && val.toString === _toString)
? JSON.stringify(val, null, 2)
: String(val)
}
将值转换为字符串,首先先解析传入的值是否为空?如果不为空,Array.isArray() 用于确定传递的值是否是一个 Array,或者是{}
JSON.stringify这个函数的作用主要是为了系列化对象的,Array或者{}都不成立就直接使用String()转成字符串;
toString(undefined) // '';
传入undefined,返回的是空字符串,我才想起来,undefined == null,返回的是true;
function toNumber (val) {
var n = parseFloat(val);
return isNaN(n) ? val : n
}
将输入值转换为数字,如果转换失败,返回传入的原值;
makeMap('slot,component', true);//调用方法;
makeMap('slot,component', true)('slot')//检查检查key值是否在这个map集合里,结果返回ture
function makeMap (
str,
expectsLowerCase
) {
var map = Object.create(null);//创建一个新对象
var list = str.split(',');//解析str,以逗号分割得到结果["slot", "component"]
for (var i = 0; i < list.length; i++) {//遍历list,放进map集合里。得到的结果{slot: true, component: true}
map[list[i]] = true;
}
return expectsLowerCase
? function (val) { return map[val.toLowerCase()]; } //第二个参数为true返回此方法(把大写转为小写),返回值为true/false;
: function (val) { return map[val]; } //第二个参数为false返回此方法,返回值为true/false;
}
这个函数有两个参数,第一个参数需要传入(“name,age”),中间有逗号隔开的格式,第二个参数只要为true,就可以把大写字母转为小写字母。Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。
//检查标记是否为内置标记
var isBuiltInTag = makeMap('slot,component', true);
// 检查属性是否为保留属性
var isReservedAttribute = makeMap('key,ref,slot,slot-scope,is');
上面👆这两句代码以后再其他地方使用到就能理解这样写的用途吧!
function remove (arr, item) {
if (arr.length) {
var index = arr.indexOf(item);
if (index > -1) {
return arr.splice(index, 1)
}
}
}
移除数组的某一项。这个函数还是经常会出现在项目里的util.js里,大家都懂得!
var hasOwnProperty = Object.prototype.hasOwnProperty;
function hasOwn (obj, key) {
return hasOwnProperty.call(obj, key)
}
这个函数是检查一个对象是否包含所需属性。返回值为true/false;如果用Object.create(null)创建的对象,这个方法obj.hasOwnProperty(key)不可用,亲们,也可以自己试一下,👇是我测试的
var a = Object.create(null);
a.name = "yy";
console.log(a.hasOwnProperty('name'));//报错内容Uncaught TypeError: a.hasOwnProperty is not a function。
hasOwnProperty.call(obj, key);//为什么这样写是有一定的道理的哈!
console.log(hasOwn(a, 'name'));//返回true;
以上是今天抽空看的一些源码,记录下来也是为了方便自己查看和复习,毕竟好记性不如烂笔头嘛。下次继续更新~~,谢谢大家关注我哈😄😄😄!!!