读vue源码笔记(1)

shared/util.js

1.hasOwn

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

extend 

export function extend (to: Object, _from: ?Object): Object {
  for (const key in _from) {
    to[key] = _from[key]
  }
  return to
}

mergeField

// 对option[key]进行策略处理,默认不处理
function mergeField (key) {
    const strat = strats[key] || defaultStrat
    options[key] = strat(parent[key], child[key], vm, key)
  }

makeMap

export function makeMap (
  str: string,
  expectsLowerCase?: boolean
): (key: string) => true | void {
  const map = Object.create(null)
  const list: Array<string> = str.split(',')
  for (let i = 0; i < list.length; i++) {
    map[list[i]] = true
  }
  // 箭头函数返回的格式
  return expectsLowerCase
    ? val => map[val.toLowerCase()]
    : val => map[val]
} 

很多地方都会用到:例如”isPlainTextElement = makeMap('script,style,textarea', true)

2.getTypeIndex

function getType (fn) {
  var match = fn && fn.toString().match(/^s*function (w+)/);
  return match ? match[1] : ''   //获得函数名
}
// console.log(Boolean.toString().match(/^s*function (w+)/))
// ["function Boolean", "Boolean", index: 0, input: "function Boolean() { [native code] }", groups: undefined]
function isSameType (a, b) {
return getType(a) === getType(b)
}
function getTypeIndex (type, expectedTypes) {
  if (!Array.isArray(expectedTypes)) {
    return isSameType(expectedTypes, type) ? 0 : -1  
  }
  for (var i = 0, len = expectedTypes.length; i < len; i++) {
    if (isSameType(expectedTypes[i], type)) {
      return i
    }
  }
  return -1
}

3.proxy代理

//key a
if (!(key in vm)) {
  proxy(vm, "_props", key);
}
function noop (a, b, c) {}
var sharedPropertyDefinition = {
    enumerable: true,
    configurable: true,
    get: noop,
    set: noop
};

function proxy (target, sourceKey, key) {
    sharedPropertyDefinition.get = function proxyGetter () {
      // this为vm。
       return this[sourceKey][key]
     };
    sharedPropertyDefinition.set = function proxySetter (val) {
       this[sourceKey][key] = val;
    };
   Object.defineProperty(target, key, sharedPropertyDefinition);
}
//对vm._props进行代理。

4.toggleObserving

var shouldObserve = true;
function toggleObserving (value) {
    shouldObserve = value;
}

 5.hasProto

var hasProto = '__proto__' in {};console.log(hasProto); //true

 6.mergeOptions

export function mergeOptions (
  parent: Object,
  child: Object,
  vm?: Component
): Object {
  if (process.env.NODE_ENV !== 'production') {
    //核实子对象中components的名字合法
    checkComponents(child)
  }

  if (typeof child === 'function') {
    child = child.options
  }

  normalizeProps(child, vm)
  normalizeInject(child, vm)
  normalizeDirectives(child)
  const extendsFrom = child.extends
  if (extendsFrom) {
    parent = mergeOptions(parent, extendsFrom, vm)
  }
  if (child.mixins) {
    for (let i = 0, l = child.mixins.length; i < l; i++) {
      parent = mergeOptions(parent, child.mixins[i], vm)
    }
  }
  const options = {}
  let key
  for (key in parent) {
    mergeField(key)
  }
  for (key in child) {
    if (!hasOwn(parent, key)) {
      mergeField(key)
    }
  }
  function mergeField (key) {
    const strat = strats[key] || defaultStrat
    options[key] = strat(parent[key], child[key], vm, key)
  }
  return options
} 

 7.toArray、cached(shared/util.js)

// 形成一个新数组,该数组是 any 从 number 以后的数组。
export function toArray (list: any, start?: number): Array<any> {
  start = start || 0
  let i = list.length - start
  const ret: Array<any> = new Array(i)
  while (i--) {
    ret[i] = list[i + start]
  }
  return ret
}

// 高阶函数,对外赋值之后调用。每次调用缓存结果。

export function cached<F: Function> (fn: F): F {
   const cache = Object.create(null)
   return (function cachedFn (str: string) {
     const hit = cache[str]
     return hit || (cache[str] = fn(str))
   }: any)
} 

cached的用法如下:

function cached(fn) {
  const cache = Object.create(null)
  return (function cachedFn (str) {
    const hit = cache[str]
    return hit || (cache[str] = fn(str))
  })
}
let f = function (x) {
    return x*x
}
let k1 = cached(f)
let k2 = k1('7')
console.log('k2=',k2)  //k2= 49
let k3 = k1('7')
console.log('k3=',k3)  //k3=49 

以 _和$开头的变量或者方法的key, 

/**
 * Check if a string starts with $ or _
 */
export function isReserved (str: string): boolean {
  const c = (str + '').charCodeAt(0)
  return c === 0x24 || c === 0x5F
}

 

原文地址:https://www.cnblogs.com/liuyinlei/p/9372022.html