【Vue】源码解析

2021/09/09 10:08:09

工具方法

这里记录 vue 中封装的部分工具方法,学习其封装函数的思路

  1. makeMap(str,bollean) 保存预设好的,可检索的字段,之后用于检测某一个字段是不是在这个预设表里

闭包

// 传入字符串, 把字符串分加入到对象中,值为true
// 返回一个函数, 后续就给这个函数传参看这个参数是不是被包含在之前定义好的字段中
// 二参控制是否强制转换为小写
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];
      };
}
const isBuiltInTag = makeMap("slot,component", true);
isBuiltInTag("slot"); // true
  1. cached(fn) 创建一个函数的带缓存版本,有缓存时直接返回缓存数据,不执行函数

闭包,每次调用带缓存函数传入不同参数都会给闭包中加入数据,造成内存泄露 适用于被多次调用且参数相同的函数,字符校验,

// 创建一个函数的带缓存版本, 用闭包来保存每次执行的结果,如果后续传入相同的参数则不执行函数,而是直接返回缓存数据
function cached(fn) {
  var cache = Object.create(null);
  return function cachedFn(str) {
    var hit = cache[str];
    // 缓存中没有这次的参数时执行函数并记录到缓存中
    return hit || (cache[str] = fn(str));
  };
}

陌生的方法/属性/其他

这里记录 vue 中使用到的之前没有接触或了解不深的技巧和骚操作

  1. reg.source 返回一个正则表达式的原始值, 如: /^_\$$/.source === ^_\$$
  2. var hasProto = '__proto__' in {}; 判断当前环境下__proto__是否可用
  3. ({}).toString.call('') 直接用 {}.toString 形式无法调用 toString 方法,用括号围起来相当于先执行括号运算符(返回对象),然后就可以调用方法了,其他类型数据亦可
  4. 定义/触发自定义事件
// 用 CustomEvent构造器new一个新事件,一参为事件名,二参为事件对象上的属性
var myEvent = new CustomEvent("event_name", {
  detail: { title: "This is title!" },
});

// 绑定事件
window.addEventListener("event_name", function(e) {
  console.log(e.detail.title);
});

// 触发事件
window.dispatchEvent(myEvent);
  1. /native code/.test([].concat.toString()) 判断方法是不是原生的
  2. _Set = /*@__PURE__*/ (function () {}) js 一行代码间插入注释
  3. Object.defineProperties(obj,props) 在一个对象上定义新属性或修改现有属性(可枚举性,get,set 等),返回该对象,一参为目标对象,二参为配置对象
var obj = Object.defineProperties(
  {},
  {
    age: {
      value: 999,
    },
  }
);
obj.age; // 999
  1. watch: {'$route': 'fetchData'} 如果路由有变化,直接执行一个方法
  2. var arrayMethods = Object.create(Array.prototype); 创建一个拥有 Array 原型的对象,也就拥有了 Array 的所有方法
  3. Object.getOwnPropertyNames(obj) 用于返回对象所有的属性键名(返回数组),包括不可枚举属性,而keys方法只返回可枚举属性
  4. for (var e = (void 0), i = 0, l = value.length; i < l; i++){} for 循环时把赋值语句放到第一个封号前避免重复取值

???

  1. if (text === void 0) text = ''; text === undefined
  2. function no(){return false}; function newFn = no;
  3. var getName = function getName(){} 给匿名函数名字?