美文网首页
React源码中的小方法

React源码中的小方法

作者: 殊一ONLY | 来源:发表于2017-12-19 19:47 被阅读0次
1.将对象解析成字符串
function friendlyStringify(obj) {
  if (typeof obj === 'object') {
    if (Array.isArray(obj)) {
      return '[' + obj.map(friendlyStringify).join(', ') + ']';
    } else {
      var pairs = [];
      for (var key in obj) {
        if (Object.prototype.hasOwnProperty.call(obj, key)) {
          var keyEscaped = /^[a-z$_][\w$_]*$/i.test(key) ? key : JSON.stringify(key);
          pairs.push(keyEscaped + ': ' + friendlyStringify(obj[key]));
        }
      }
      return '{' + pairs.join(', ') + '}';
    }
  } else if (typeof obj === 'string') {
    return JSON.stringify(obj);
  } else if (typeof obj === 'function') {
    return '[function object]';
  }
  // Differs from JSON.stringify in that undefined because undefined and that
  // inf and nan don't become null
  return String(obj);
}

      首先对传入参数的数据类型进行分析Object,String,Function。如果是Object判断该Object是否为Array,如果是则递归遍历其内部的每一项。否则遍历Object内部的每一项将key和value做处理后存储到数值pairs中,并将pairs格式化为字符串返回。

2.累积函数accumulateInto和accumulate

      accumulate()函数将current与next进行拼接:

function accumulate(current, next) {
   if (current == null) {
    return next;
  }
  // Both are not empty. Warning: Never call x.concat(y) when you are not
  // certain that x is an Array (x could be a string with concat method).
//数组拼接成一个新的数组(或队列)
  if (Array.isArray(current)) {
    return current.concat(next);
  }

  if (Array.isArray(next)) {
    return [current].concat(next);
  }
// 非数组,则
  return [current, next];
}

      accumulateInto()函数将next写入current数组中(或队列里)

function accumulateInto(current, next) {
  if (current == null) {
    return next;
  }
  // Both are not empty. Warning: Never call x.concat(y) when you are not
  // certain that x is an Array (x could be a string with concat method).
  if (Array.isArray(current)) {
if (Array.isArray(next)) {
// 将next输入写入当前数组中
      current.push.apply(current, next);
      return current;
    }
    current.push(next);
    return current;
  }
// current不是数组,next是数组
  if (Array.isArray(next)) {
    // A bit too dangerous to mutate `next`.
    return [current].concat(next);
  }
// 两个都不是数组
  return [current, next];
}
5.合成事件的函数

5.1获取事件target

function getEventTarget(nativeEvent) {
// 兼容性问题
  var target = nativeEvent.target || nativeEvent.srcElement || window;
  // Normalize SVG <use> element events #4963
  if (target.correspondingUseElement) {
    target = target.correspondingUseElement;
  }

  // Safari may fire events on text nodes (Node.TEXT_NODE is 3).
  // @see http://www.quirksmode.org/js/events_properties.html
  return target.nodeType === 3 ? target.parentNode : target;
}

5.2阻止合成事件的默认事(SyntheticEvent.js中)

preventDefault: function () {
    this.defaultPrevented = true;
    var event = this.nativeEvent;
    if (!event) {
      return;
    }
    if (event.preventDefault) {
      event.preventDefault();
      // eslint-disable-next-line valid-typeof
    } else if (typeof event.returnValue !== 'unknown') {
      event.returnValue = false;
    }
    this.isDefaultPrevented = emptyFunction.thatReturnsTrue;
  }

5.3 阻止合成事件冒泡

stopPropagation: function () {
    var event = this.nativeEvent;
    if (!event) {
      return;
    }
    if (event.stopPropagation) {
      event.stopPropagation();
          } else if (typeof event.cancelBubble !== 'unknown') {
      event.cancelBubble = true;
    }
    this.isPropagationStopped = emptyFunction.thatReturnsTrue;
  }

5.4遍历合成事件的事件队列

@param arr 事件队列
@param cb 事件执行完后的回调函数
@param scope 定义域
function forEachAccumulated(arr, cb, scope) {
  if (Array.isArray(arr)) {
    arr.forEach(cb, scope);
  } else if (arr) {
    cb.call(scope, arr);
  }
}

5.5 EventCharCode
获取键盘字符,区分大小写

function getEventCharCode(nativeEvent) {
  var charCode;
  var keyCode = nativeEvent.keyCode;
  if ('charCode' in nativeEvent) {
    charCode = nativeEvent.charCode;
    // FF does not set `charCode` for the Enter-key, check against `keyCode`.
    if (charCode === 0 && keyCode === 13) {
      charCode = 13;
    }
  } else {
    // IE8 does not implement `charCode`, but `keyCode` has the correct value.
    charCode = keyCode;
  }
  // Some non-printable keys are reported in `charCode`/`keyCode`, discard them.
  // Must not discard the (non-)printable Enter-key.
  if (charCode >= 32 || charCode === 13) {
    return charCode;
  }
  return 0;
}

5.6遍历所有的祖先节点

var ancestor = targetInst;
  do {
    bookKeeping.ancestors.push(ancestor);
    ancestor = ancestor && findParent(ancestor);
  } while (ancestor);
向上寻找父节点的方法findParent
function findParent(inst) {
  // TODO: It may be a good idea to cache this to prevent unnecessary DOM
  // traversal, but caching is difficult to do correctly without using a
  // mutation observer to listen for all DOM changes.
  while (inst._hostParent) {
    inst = inst._hostParent;
  }
  var rootNode = ReactDOMComponentTree.getNodeFromInstance(inst);
  var container = rootNode.parentNode;
  return ReactDOMComponentTree.getClosestInstanceFromNode(container);
}

相关文章

网友评论

      本文标题:React源码中的小方法

      本文链接:https://www.haomeiwen.com/subject/qnpiwxtx.html