最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JS面試必備之手寫instanceof,深拷貝,節(jié)流和防抖

 更新時間:2023年05月19日 10:28:44   作者:feelingHy  
JavaScript如何實現(xiàn)手寫instanceof、深拷貝、節(jié)流、防抖也是面試時常??嫉降闹R點,這篇文章為大家進行了詳細介紹,需要的可以參考一下

一、instanceof 的實現(xiàn)

使用 instanceof 操作符,如果一個實例的原型鏈中出現(xiàn)過相應(yīng)的構(gòu)造函數(shù)的原型,則 instanceof 返回 true。

instanceof 主要的實現(xiàn)原理就是只要右邊變量的 prototype 在左邊變量的原型鏈上即可。 因此,instanceof 在查找的過程中會遍歷左邊變量的原型鏈,直到找到右邊變量的 prototype,如果查找失敗,則會返回 false,告訴我們左邊變量并非是右邊變量的實例。

function instanceof1(L,R) {
  L = L.__proto__;

  while(L != null) {
    if(L === R.prototype) {
      return true;
    }
    L = L.__proto__;
  }
  return false;
}

二、淺拷貝

// 淺拷貝
function shallowClone(obj) {
  const result = {};
  for(let key in obj) {
    console.log('ddddd',key);
    if(obj.hasOwnProperty(key)) {
      result[key] = obj[key];
    }
  }
  return result;
}

測試代碼:

let obj = {
  b: {
    c: [1, 5, 11, 23, 422]
  },
  d: function() {
    console.log('hello world');
  }
};
const result = shallowClone(obj);
console.log(result);
const newObj = Object.assign({},obj);
console.log(newObj);

三、深拷貝

// 深拷貝
function deepClone(obj) {
  if(typeof obj != 'object' || obj == null) {
    return obj;
  }
  const result = Array.isArray(obj) ? [] : {};
  for(let key in obj) {
    // 自有屬性
    if(obj.hasOwnProperty(key)) {
      const type = typeof obj[key];
      if(type == 'object' && obj[key] != null) {
        result[key] = deepClone(obj[key]);
      } else {
        result[key] = obj[key];
      }
    }
  }
  return result;
}

測試代碼:

var data = {
  age: 18,
  name: "liuruchao",
  education: ["小學(xué)", "初中", "高中", "大學(xué)", undefined, null],
  likesFood: new Set(["fish", "banana"]),
  friends: [
        { name: "summer",  sex: "woman"},
        { name: "daWen",   sex: "woman"},
        { name: "yang",    sex: "man" }  ],
  work: {
          time: "2019",
          project: { name: "test",obtain: ["css", "html", "js"]}
        },
  play: function() {    console.log("玩滑板");  }
}
console.log(deepClone(data));

解決循環(huán)引用問題:

// 解決循環(huán)引用問題
function deepClone2(obj, hash = new WeakMap()) {
  const type = typeof obj;
  if(type != 'object' || obj == null) {
    return obj;
  }
  if(hash.has(obj)) {
    return hash.get(obj);
  }
  const result = Array.isArray(obj) ? [] : {};
  for(let key in obj) {
    if(obj.hasOwnProperty(key)) {
      if(typeof obj[key] != 'object' || obj[key] == null) {
        result[key] = obj[key];
      } else {
        // 首次調(diào)用時,weakMap為空,不會走上面那個if(hash.has())語句,如果待拷貝對象中有屬性也為對象時,
        // 則將該待拷貝對象存入weakMap中,此時的健值和健名都是對該待拷貝對象的引用
        hash.set(obj, obj)
        result[key] = deepClone2(obj[key], hash);
      }
    }
  }
  return result;
}

測試代碼:

var data2 = {
  name: 'foo',
  child: null,
}
data2.child = data2;
console.log(deepClone2(data2));

四、函數(shù)防抖

  • 當持續(xù)觸發(fā)事件時,一定時間內(nèi)沒有再觸發(fā)事件,事件處理函數(shù)才會執(zhí)行一次;
  • 如果在設(shè)定的時間來到之前,又一次觸發(fā)了事件,則會取消上次事件,重新開始計時;

使用場景:resize、scroll、輸入框內(nèi)容校驗等。

function debounce(handle,wait) {
  let timer = null;
  return function () {
    if(timer != null) {
      clearTimeout(timer);
    }
    timer = setTimeout(handle, wait);
  }
}

五、節(jié)流

當持續(xù)觸發(fā)事件時,保證一定時間內(nèi)只調(diào)用一次事件處理函數(shù)。通俗解釋就比如:我們把水龍頭打開,水嘩嘩的往外流,秉著節(jié)約的原則,我們要把水龍頭關(guān)小,最好是如我們的心愿按照一定的規(guī)律,在某個時間內(nèi)一滴一滴的往下滴。

時間戳版本:

function throttle (handle,wait) {
  let prev = Date.now();
  return function() {
    let current = Date.now();
    if(current - prev >= wait) {
      handle();
      prev = Date.now();
    }
  }
}

定時器版本:

  • 當觸發(fā)事件的時候,我們設(shè)置一個定時器;
  • 當再次觸發(fā)的時候,如果定時器存在,就不執(zhí)行,直到 wait 時間后,定時器執(zhí)行 handle 函數(shù),并且清空定時器,這樣就可以設(shè)置下一個定時器;
  • 當?shù)谝淮斡|發(fā)事件時,不會立即執(zhí)行行數(shù),而是在 delay 秒之后才執(zhí)行,而后在怎么頻繁觸發(fā)也都是在 wait 時間才執(zhí)行一次。
function throttle1(handle, wait) {
  let timer = null;
  return function() {
    if(!timer) {
      timer = setTimeout(() => {
        handle();
        timer = null;
      },wait);
    }
  }
}

定時器 + 時間戳版本:

  • 節(jié)流中使用時間戳和定時器版本都是可以的,更精確的,可以使用時間戳和定時器相結(jié)合,當?shù)谝淮问录|發(fā)時馬上執(zhí)行事件處理函數(shù),最后一次觸發(fā)時也還會執(zhí)行一次事件處理函數(shù)。
  • 在節(jié)流函數(shù)內(nèi)部使用了 pre 和 current 與 wait 來計算剩余時間 remaining,當 remaining <= 0 時,表示執(zhí)行該執(zhí)行事件處理函數(shù)了(保證了第一次觸發(fā)事件就能立即執(zhí)行事件處理函數(shù)和每隔 wait 時間執(zhí)行一次事件處理函數(shù))。
  • 如果還沒到時間的話就設(shè)定在remaining時間后再觸發(fā) (保證了最后一次觸發(fā)事件后還能再執(zhí)行一次事件處理函數(shù))。當然在 remaining 這段時間中如果又一次觸發(fā)事件,那么會取消當前的計時器,并重新計算一個remaining來判斷當前狀態(tài)。
function throttle2 (handle, wait) {
  let pre = Date.now();
  let timer = null;
  return function() {
    let current = Date.now();
    let remaining = wait - (current - pre);
    clearTimeout(timer);
    if(remaining <= 0) {
      handle();
      pre = Date.now();
    } else {
      timer = setTimeout(handle, remaining);
    }
  }
}

節(jié)流和防抖總結(jié):

  • 函數(shù)防抖:將幾次操作合并為一次操作進行。原理是維護一個計時器,規(guī)定在delay時間后觸發(fā)函數(shù),但是在delay 時間內(nèi)再次觸發(fā)的話,就會取消之前的計時器而重新設(shè)置。這樣一來,只有最后一次操作能被觸發(fā)。
  • 函數(shù)節(jié)流:使得一定時間內(nèi)只觸發(fā)一次函數(shù)。原理是通過判斷是否到達一定時間來觸發(fā)函數(shù)。
  • 區(qū)別: 函數(shù)節(jié)流不管事件觸發(fā)有多頻繁,都會保證在規(guī)定時間內(nèi)一定會執(zhí)行一次真正的事件處理函數(shù),而函數(shù)防抖只是在最后一次事件后才觸發(fā)一次函數(shù)。比如在頁面的無限加載場景下,我們需要用戶在滾動頁面時,每隔一段時間發(fā)一次 Ajax 請求,而不是在用戶停下滾動頁面操作時才去請求數(shù)據(jù)。這樣的場景,就適合用節(jié)流技術(shù)來實現(xiàn)。

以上就是JS面試必備之手寫instanceof,深拷貝,節(jié)流和防抖的詳細內(nèi)容,更多關(guān)于JS面試的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • javascript實現(xiàn)上傳圖片并預(yù)覽的效果實現(xiàn)代碼

    javascript實現(xiàn)上傳圖片并預(yù)覽的效果實現(xiàn)代碼

    圖片上傳預(yù)覽,就是在使用文件選擇框選擇了文件之后就可以在頁面上看見圖片的效果,關(guān)于這個效果我一直認為是無法做到的
    2011-04-04
  • freemarker判斷對象是否為空的方法

    freemarker判斷對象是否為空的方法

    FreeMarker是一個用Java語言編寫的模板引擎,它基于模板來生成文本輸出,用FreeMarker判斷對象是否為空的方法大家知道嗎,這篇文章就針對這個知道點做介紹,需要的朋友可以參考下
    2015-08-08
  • h5后臺切換檢測利用visibilitychange的缺點超詳細分析

    h5后臺切換檢測利用visibilitychange的缺點超詳細分析

    在移動端的H5應(yīng)用場景中,用戶經(jīng)常會將頁面切到后臺再切回前臺,瀏覽器對后臺頁面的資源調(diào)度、定時任務(wù)執(zhí)行和網(wǎng)絡(luò)請求策略會產(chǎn)生顯著變化,這篇文章主要介紹了h5后臺切換檢測利用visibilitychange的缺點分析的相關(guān)資料,需要的朋友可以參考下
    2026-03-03
  • 手機端js和html5刮刮卡效果

    手機端js和html5刮刮卡效果

    這篇文章主要為大家詳細介紹了手機端js和html5刮刮卡效果,刮開之后是隨機生成的8位碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-01-01
  • javascript實現(xiàn)留言板功能

    javascript實現(xiàn)留言板功能

    這篇文章主要為大家詳細介紹了javascript實現(xiàn)留言板功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • 微信小程序?qū)崿F(xiàn)滑動刪除

    微信小程序?qū)崿F(xiàn)滑動刪除

    這篇文章主要為大家詳細介紹了微信小程序?qū)崿F(xiàn)滑動刪除,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • 關(guān)于vite?+?ts?找不到模塊@/xxxx?或其相應(yīng)的類型聲明問題

    關(guān)于vite?+?ts?找不到模塊@/xxxx?或其相應(yīng)的類型聲明問題

    這篇文章主要介紹了vite?+?ts?找不到模塊@/xxxx?或其相應(yīng)的類型聲明,本文通過示例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-06-06
  • 深入理解JavaScript的async/await

    深入理解JavaScript的async/await

    我們給大家分享了關(guān)于JavaScript的async/await的相關(guān)知識點內(nèi)容,有需要的朋友們可以學(xué)習(xí)下。
    2018-08-08
  • 真正好用的js驗證上傳文件大小的簡單方法

    真正好用的js驗證上傳文件大小的簡單方法

    下面小編就為大家?guī)硪黄嬲糜玫膉s驗證上傳文件大小的簡單方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-10-10
  • 深入淺析Node環(huán)境和瀏覽器的區(qū)別

    深入淺析Node環(huán)境和瀏覽器的區(qū)別

    最近有朋友問我node環(huán)境和瀏覽器的區(qū)別這一問題,今天小編就抽空給大家介紹下Node環(huán)境和瀏覽器的區(qū)別,感興趣的朋友一起看看吧
    2018-08-08

最新評論

玉环县| 夹江县| 贵德县| 禄劝| 渭南市| 余江县| 芦溪县| 洪湖市| 民丰县| 宜黄县| 个旧市| 安国市| 吉木萨尔县| 西华县| 蓬安县| 汉寿县| 武宣县| 德惠市| 华坪县| 安乡县| 镶黄旗| 胶南市| 宁河县| 涪陵区| 盐城市| 白银市| 桂阳县| 萨迦县| 大悟县| 吉安县| 白沙| 武功县| 蛟河市| 永吉县| 宁晋县| 太仆寺旗| 洛宁县| 五莲县| 二连浩特市| 金堂县| 通化县|