国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

react源碼ReactTreeTraversal.js之?dāng)?shù)據(jù)結(jié)構(gòu)與算法

makeFoxPlay / 3510人閱讀

摘要:面試中,經(jīng)常遇到的一個(gè)簡(jiǎn)單算法題查找兩個(gè)單鏈表的公共節(jié)點(diǎn)最近在讀源碼的時(shí)候發(fā)現(xiàn)一個(gè)樹中對(duì)該算法的運(yùn)用見函數(shù),在此做簡(jiǎn)單的記錄。地址在樹中獲取當(dāng)前實(shí)例節(jié)點(diǎn)的父節(jié)點(diǎn)實(shí)例組件對(duì)應(yīng)的,比如的表示為類組件,其為對(duì)應(yīng)元素。

面試中,經(jīng)常遇到的一個(gè)簡(jiǎn)單算法題:查找兩個(gè)單鏈表的公共節(jié)點(diǎn)
最近在讀react源碼的時(shí)候發(fā)現(xiàn)一個(gè)react樹中對(duì)該算法的運(yùn)用(見getLowestCommonAncestor函數(shù)),在此做簡(jiǎn)單的記錄。
git地址

getParent

在react樹中獲取當(dāng)前實(shí)例節(jié)點(diǎn)的父節(jié)點(diǎn)實(shí)例

//HostComponent組件對(duì)應(yīng)的DOM,比如App的tag=3, 表示為類組件,其child為tag=5對(duì)應(yīng)div元素。
function getParent(inst) {
  do {
    inst = inst.return;
    // TODO: If this is a HostRoot we might want to bail out.
    // That is depending on if we want nested subtrees (layers) to bubble
    // events to their parent. We could also go through parentNode on the
    // host node but that wouldn"t work for React Native and doesn"t let us
    // do the portal feature.
  } while (inst && inst.tag !== HostComponent);
  if (inst) {
    return inst;
  }
  return null;
}
getLowestCommonAncestor

獲取節(jié)點(diǎn)A與B的最近的公共祖先節(jié)點(diǎn)

算法題:找到兩個(gè)鏈表的公共節(jié)點(diǎn)

export function getLowestCommonAncestor(instA, instB) {
  //獲取子節(jié)點(diǎn)A在樹中的深度
  let depthA = 0;
  for (let tempA = instA; tempA; tempA = getParent(tempA)) {
    depthA++;
  }
    //獲取子節(jié)點(diǎn)B在樹中的深度
  let depthB = 0;
  for (let tempB = instB; tempB; tempB = getParent(tempB)) {
    depthB++;
  }

  // If A is deeper, crawl up.
  // 如果A的高度高,那么A節(jié)點(diǎn)先往上走depthA - depthB個(gè)節(jié)點(diǎn),最后同時(shí)走,直到父節(jié)點(diǎn)是同一個(gè)
  while (depthA - depthB > 0) {
    instA = getParent(instA);
    depthA--;
  }

    // 如果B的高度高,那么B節(jié)點(diǎn)先往上走depthB - depthB個(gè)節(jié)點(diǎn),最后同時(shí)走,直到父節(jié)點(diǎn)是同一個(gè)
  // If B is deeper, crawl up.
  while (depthB - depthA > 0) {
    instB = getParent(instB);
    depthB--;
  }

  // Walk in lockstep until we find a match.
  // 現(xiàn)在,指針?biāo)幍奈恢玫母叨纫恢拢梢酝瑫r(shí)往上查找,直到找到公共的節(jié)點(diǎn)
  let depth = depthA;
  while (depth--) {
    if (instA === instB || instA === instB.alternate) {
      return instA;
    }
    instA = getParent(instA);
    instB = getParent(instB);
  }
  return null;
}
isAncestor

判斷A節(jié)點(diǎn)是否是B節(jié)點(diǎn)的祖先節(jié)點(diǎn)

export function isAncestor(instA, instB) {
  while (instB) {
    if (instA === instB || instA === instB.alternate) {
      return true;
    }
    instB = getParent(instB);
  }
  return false;
}
getParentInstance

對(duì)getParent的export封裝:

export function getParentInstance(inst) {
  return getParent(inst);
}
traverseTwoPhase

對(duì)inst及其以上的樹執(zhí)行冒泡捕獲的操作,執(zhí)行fn。類似事件的冒泡捕獲

export function traverseTwoPhase(inst, fn, arg) {
  const path = [];
  //將inst的父節(jié)點(diǎn)入棧,數(shù)組最后的為最遠(yuǎn)的祖先
  while (inst) {
    path.push(inst);
    inst = getParent(inst);
  }
  let i;
  //從最遠(yuǎn)的祖先開始向inst節(jié)點(diǎn)捕獲執(zhí)行fn
  for (i = path.length; i-- > 0; ) {
    fn(path[i], "captured", arg);
  }
    //從inst節(jié)點(diǎn)開始向最遠(yuǎn)的祖先節(jié)點(diǎn)冒泡執(zhí)行fn
  for (i = 0; i < path.length; i++) {
    fn(path[i], "bubbled", arg);
  }
}
traverseEnterLeave

當(dāng)關(guān)注點(diǎn)從from節(jié)點(diǎn)移出然后移入to節(jié)點(diǎn)的時(shí)候,在from執(zhí)行執(zhí)行類似移入移出的操作,from節(jié)點(diǎn)

export function traverseEnterLeave(from, to, fn, argFrom, argTo) {
  const common = from && to ? getLowestCommonAncestor(from, to) : null;
  const pathFrom = [];
  while (true) {
    if (!from) {
      break;
    }
    if (from === common) {
      break;
    }
    const alternate = from.alternate;
    if (alternate !== null && alternate === common) {
      break;
    }
    pathFrom.push(from);
    from = getParent(from);
  }
  const pathTo = [];
  while (true) {
    if (!to) {
      break;
    }
    if (to === common) {
      break;
    }
    const alternate = to.alternate;
    if (alternate !== null && alternate === common) {
      break;
    }
    pathTo.push(to);
    to = getParent(to);
  }
  //以上代碼將from節(jié)點(diǎn)到from與to節(jié)點(diǎn)的最近公共祖先節(jié)點(diǎn)(不包括公共祖先節(jié)點(diǎn))push到pathFrom數(shù)組
  //以上代碼將to節(jié)點(diǎn)到from與to節(jié)點(diǎn)的最近公共祖先節(jié)點(diǎn)(不包括公共祖先節(jié)點(diǎn))push到pathTo數(shù)組

  // 以下代碼用于對(duì)pathFrom冒泡,執(zhí)行fn
  for (let i = 0; i < pathFrom.length; i++) {
    fn(pathFrom[i], "bubbled", argFrom);
  }
    // 以下代碼用于對(duì)pathTo捕獲,執(zhí)行fn
  for (let i = pathTo.length; i-- > 0; ) {
    fn(pathTo[i], "captured", argTo);
  }
}

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/102128.html

相關(guān)文章

  • Deep In React 詳談 React 16 Diff 策略(二)

    摘要:對(duì)于同一層級(jí)的一組子節(jié)點(diǎn),它們可以通過唯一進(jìn)行區(qū)分。基于以上三個(gè)前提策略,分別對(duì)以及進(jìn)行算法優(yōu)化。鏈表的每一個(gè)節(jié)點(diǎn)是,而不是在之前的虛擬節(jié)點(diǎn)。是當(dāng)前層的第一個(gè)節(jié)點(diǎn)。再次提醒,是的一層。 文章首發(fā)于個(gè)人博客 這是我 Deep In React 系列的第二篇文章,如果還沒有讀過的強(qiáng)烈建議你先讀第一篇:詳談 React Fiber 架構(gòu)(1)。 前言 我相信在看這篇文章的讀者一般都已經(jīng)了解...

    NSFish 評(píng)論0 收藏0
  • 淺談React Fiber

    摘要:因?yàn)榘姹緦⒄嬲龔U棄這三生命周期到目前為止,的渲染機(jī)制遵循同步渲染首次渲染,更新時(shí)更新時(shí)卸載時(shí)期間每個(gè)周期函數(shù)各司其職,輸入輸出都是可預(yù)測(cè),一路下來(lái)很順暢。通過進(jìn)一步觀察可以發(fā)現(xiàn),預(yù)廢棄的三個(gè)生命周期函數(shù)都發(fā)生在虛擬的構(gòu)建期間,也就是之前。 showImg(https://segmentfault.com/img/bVbweoj?w=559&h=300); 背景 前段時(shí)間準(zhǔn)備前端招聘事項(xiàng)...

    izhuhaodev 評(píng)論0 收藏0
  • FE.SRC-React實(shí)戰(zhàn)原理筆記

    摘要:異步實(shí)戰(zhàn)狀態(tài)管理與組件通信組件通信其他狀態(tài)管理當(dāng)需要改變應(yīng)用的狀態(tài)或有需要更新時(shí),你需要觸發(fā)一個(gè)把和載荷封裝成一個(gè)。的行為是同步的。所有的狀態(tài)變化必須通過通道。前端路由實(shí)現(xiàn)與源碼分析設(shè)計(jì)思想應(yīng)用是一個(gè)狀態(tài)機(jī),視圖與狀態(tài)是一一對(duì)應(yīng)的。 React實(shí)戰(zhàn)與原理筆記 概念與工具集 jsx語(yǔ)法糖;cli;state管理;jest單元測(cè)試; webpack-bundle-analyzer Sto...

    PumpkinDylan 評(píng)論0 收藏0
  • React 源碼剖析系列 - 不可思議的 react diff

    摘要:目前,前端領(lǐng)域中勢(shì)頭正盛,使用者眾多卻少有能夠深入剖析內(nèi)部實(shí)現(xiàn)機(jī)制和原理。當(dāng)發(fā)現(xiàn)節(jié)點(diǎn)已經(jīng)不存在,則該節(jié)點(diǎn)及其子節(jié)點(diǎn)會(huì)被完全刪除掉,不會(huì)用于進(jìn)一步的比較。 目前,前端領(lǐng)域中 React 勢(shì)頭正盛,使用者眾多卻少有能夠深入剖析內(nèi)部實(shí)現(xiàn)機(jī)制和原理。本系列文章希望通過剖析 React 源碼,理解其內(nèi)部的實(shí)現(xiàn)原理,知其然更要知其所以然。 React diff 作為 Virtual DOM 的加速...

    shuibo 評(píng)論0 收藏0
  • 論一個(gè)前端工程師如何快速學(xué)習(xí),成長(zhǎng)。準(zhǔn)備自己的35歲 【-原創(chuàng)精讀】

    showImg(https://segmentfault.com/img/bVbw3tK?w=1240&h=827); 前端工程師這個(gè)崗位,真的是反人性的 我們來(lái)思考一個(gè)問題: 一個(gè)6年左右經(jīng)驗(yàn)的前端工程師: 前面兩年在用jQuery 期間一直在用React-native(一步一步踩坑過來(lái)的那種) 最近兩年還在寫微信小程序 下面一個(gè)2年經(jīng)驗(yàn)的前端工程師: 并不會(huì)跨平臺(tái)技術(shù),他的兩年工作都是Reac...

    RdouTyping 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<