亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

2020年12道高頻JavaScript手寫(xiě)面試題及答案

  發(fā)布時(shí)間:2020-01-06 16:21:47   作者:小耿學(xué)前端   我要評(píng)論
這篇文章主要介紹了2020年12道高頻JavaScript手寫(xiě)面試題及答案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

JavaScript筆試部分

本文分享 12 道高頻JavaScript的面試題,包含手寫(xiě)以及常用的正則。

實(shí)現(xiàn)防抖函數(shù) (debounce)

防抖函數(shù)原理 : 在事件被觸發(fā)n秒后在執(zhí)行回調(diào),如果在這n秒內(nèi)又被觸發(fā),則重新計(jì)時(shí)。

那么與節(jié)流函數(shù)的區(qū)別直接看這個(gè)動(dòng)畫(huà)實(shí)現(xiàn)即可。

手寫(xiě)簡(jiǎn)化版

//防抖函數(shù)
const debounce = (fn,delay)=>{
    let timer = null;
    return (...args)=>{
        clearTimeout(timer);
        timer = setTimeout(()=>{
        fn.apply(this,args)
        },delay);
    };
};

適用場(chǎng)景 :

  • 按鈕提交場(chǎng)景: 防止多次提交按鈕,只執(zhí)行最后提交的一次
  • 服務(wù)端驗(yàn)證場(chǎng)景 : 表單驗(yàn)證需要服務(wù)端配合,只執(zhí)行一段連續(xù)的輸入事件的最后一次,還有搜索聯(lián)想詞功能類(lèi)似

生存環(huán)境請(qǐng)用lodash.debounce

實(shí)現(xiàn)節(jié)流函數(shù) (throttle)

防抖函數(shù)原理:規(guī)定在一單位時(shí)間內(nèi)。只能觸發(fā)一次函數(shù)。如果這個(gè)單位時(shí)間內(nèi)觸發(fā)多次函數(shù),只有一次生效。

//手寫(xiě)簡(jiǎn)化版
//節(jié)流函數(shù)
const throttle = (fn,delay = 500) =>{
    let flag = true;
    return (...args) =>{
        if (!flag) return;
        flag = false;
        setTimeout(() => {
        fn.apply(this,args)
        },delay);
    };
};

適用場(chǎng)景:

  • 拖拽場(chǎng)景: 固定時(shí)間內(nèi)只執(zhí)行一次,防止超高頻次觸發(fā)位置變動(dòng)
  • 縮放場(chǎng)景: 監(jiān)控瀏覽器resize
  • 動(dòng)畫(huà)場(chǎng)景: 避免短時(shí)間內(nèi)多次觸發(fā)動(dòng)畫(huà)引起性能問(wèn)題

深克隆 (deepclone)

簡(jiǎn)單版 :

const newObj = JSON.parse(JSON.stringify(oldObj));

局限性 :
1、他無(wú)法實(shí)現(xiàn)函數(shù)、RegExp等特殊對(duì)象的克隆
2、會(huì)拋棄對(duì)象的constructor,所有的構(gòu)造函數(shù)會(huì)指向Object
3、對(duì)象有循環(huán)引用,會(huì)報(bào)錯(cuò)

實(shí)現(xiàn)Event (event bus)

event bus既是node中各個(gè)模塊的基石,又是前端組件通信的依賴(lài)手段之一,同時(shí)涉及了訂閱-發(fā)布設(shè)計(jì)模式,是非常重要的基礎(chǔ)。

簡(jiǎn)單版:

class EventEmeitter {
    constructor(){
        this._events = this._events || new Map(); //儲(chǔ)存事件/回調(diào)鍵值對(duì)
        this._maxListeners = this._maxListeners || 1o;//設(shè)立監(jiān)聽(tīng)上限
    }
}

//觸發(fā)名為type的事件
EventEmeitter.prototype.emit = function(type,...args){
    let hander;
    //從儲(chǔ)存事件鍵值對(duì)的this._events中獲取對(duì)應(yīng)事件回調(diào)函數(shù)
    handler = this._events.get(type);
    if (args.length > 0) {
        hander.apply(this,args);
    }else{
        handler.call(this);
    }
    return true;
};

//監(jiān)聽(tīng)名為type事件
EventEmeitter.prototype.addListener = function(type,fn) {
    //將type事件以及對(duì)應(yīng)的fn函數(shù)放入this._events中儲(chǔ)存
    if (!this._events.get(type)) {
        this._events.set(type,fn);
    }
};

實(shí)現(xiàn)instanceOf

//模擬 instanceof
function instance_of(L,R){
    var O = R.prototype;//取 R 的顯示原型
    L = L.__proto__;//取 L 的隱式原型
    while (true) {
        if (L === null) return false;
        if (O === L)
        // 這里重點(diǎn) : 當(dāng) O 嚴(yán)格等于 L 時(shí),返回 true
        return true;
        L = L.__proto__;
    }
}

模擬new

new操作符做了這些事:

  • 他創(chuàng)建了一個(gè)全新的對(duì)象
  • 他會(huì)被執(zhí)行[[Prototype]] (也就是__proto__) 鏈接
  • 它使this指向新創(chuàng)建的對(duì)象
  • 通過(guò)new創(chuàng)建的每個(gè)對(duì)象將最終被[[Prototype]]鏈接到這個(gè)函數(shù)的prototype對(duì)象上
  • 如果函數(shù)沒(méi)有返回對(duì)象類(lèi)型Object(包含F(xiàn)unction,Array,Date,RegExg,Error),那么new表達(dá)式中的函數(shù)調(diào)用將返回對(duì)象引用
// objectFactory(name,'cxk','18')
function objectFactory(){
    const obj = new object();
    const Constructor = [].shift.call(arguments);
    
    obj.__proto__ = Constructor.prototype;
    
    const ret = Constructor.apply(obj,arguments);
    
    return typeof ret === "object" ? ret : obj;
}

實(shí)現(xiàn)一個(gè)call

call做了什么 :

  • 將函數(shù)設(shè)為對(duì)象的屬性
  • 執(zhí)行&刪除這個(gè)函數(shù)
  • 指定this到函數(shù)并傳人給定參數(shù)執(zhí)行函數(shù)
  • 如果不傳人參數(shù),默認(rèn)指向?yàn)?window
//模擬 call bar.mycall(null);
//實(shí)現(xiàn)一個(gè)call方法;
Function.prototype.myCall = function(context){
    //此處沒(méi)有考慮context非object情況
    context.fn = this;
    let args = [];
    for (let i = 1,len = arguments.length,i < len; i++){
        args.push(arguments[i]);
    }
    context.fn(...args);
    let result = context.fn(...args);
    delete context.fn;
    return result;
};

實(shí)現(xiàn)apply方法

apply原理與call很相似,不多獒數(shù)

//模擬 apply
Function.prototype.myapply = function(context,arr){
    var context = Object(context) || window;
    context.fn = this;
    
    var result;
    if (!arr){
        result = context.fn();
    }else{
        var args = [];
        for (var i = 0,len = arr.length;i < len; i++){
            args.push("arr["+ i +"]");
        }
        result = eval("context.fn("+ args + ")");
    }
    delete context.fn;
    return result;
}

實(shí)現(xiàn)bind

實(shí)現(xiàn)bind要做什么

  • 返回一個(gè)函數(shù),綁定this,傳遞預(yù)置參數(shù)
  • bind返回的函數(shù)可以作為構(gòu)造函數(shù)使用。故作為構(gòu)造函數(shù)時(shí)應(yīng)使得this失效,但是傳人的參數(shù)依然有效

 

// mdn的實(shí)現(xiàn)
if (!Function.prototype.bind) {
  Function.prototype.bind = function(oThis) {
    if (typeof this !== 'function') {
      // closest thing possible to the ECMAScript 5
      // internal IsCallable function
      throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
    }

    var aArgs   = Array.prototype.slice.call(arguments, 1),
        fToBind = this,
        fNOP    = function() {},
        fBound  = function() {
          // this instanceof fBound === true時(shí),說(shuō)明返回的fBound被當(dāng)做new的構(gòu)造函數(shù)調(diào)用
          return fToBind.apply(this instanceof fBound
                 ? this
                 : oThis,
                 // 獲取調(diào)用時(shí)(fBound)的傳參.bind 返回的函數(shù)入?yún)⑼沁@么傳遞的
                 aArgs.concat(Array.prototype.slice.call(arguments)));
        };

    // 維護(hù)原型關(guān)系
    if (this.prototype) {
    }
    // 下行的代碼使fBound.prototype是fNOP的實(shí)例,因此
    // 返回的fBound若作為new的構(gòu)造函數(shù),new生成的新對(duì)象作為this傳入fBound,新對(duì)象的__proto__就是fNOP的實(shí)例
    fBound.prototype = new fNOP();

    return fBound;
  };
}

詳解請(qǐng)移步JavaScript深入之bind的模擬實(shí)現(xiàn) #12

模擬Object.create

Object.create()方法創(chuàng)建一個(gè)新對(duì)象,使用現(xiàn)有的對(duì)象來(lái)提供新創(chuàng)建的對(duì)象的__proto__。
// 模擬 Object.create

function create(proto) {
  function F() {}
  F.prototype = proto;

  return new F();
}

模擬Object.create

Object.create() 方法創(chuàng)建一個(gè)新對(duì)象,使用現(xiàn)有的對(duì)象來(lái)提供新創(chuàng)建的對(duì)象的__proto__。

// 模擬 object.create

function create(proto){
    function F(){
        F.prototype = proto;
        
        return new F();
    }
}

解析 URL Params為對(duì)象

let url = 'http://www.domain.com/?user=anonymous&id=123&id=456&city=%E5%8C%97%E4%BA%AC&enabled';
parseParam(url)

/* 結(jié)果
{ user: 'anonymous',
  id: [ 123, 456 ], // 重復(fù)出現(xiàn)的 key 要組裝成數(shù)組,能被轉(zhuǎn)成數(shù)字的就轉(zhuǎn)成數(shù)字類(lèi)型
  city: '北京', // 中文需解碼
  enabled: true, // 未指定值得 key 約定為 true
}
*/

轉(zhuǎn)化為駝峰命名

var s1 = "get-element-by-id"

//轉(zhuǎn)化為 getElementById

var f = function(s){
    return s.replace(/-\w/g,function(x){
      return x.slice(1).toUpperCase(); 
    })
}

本文主要是一些基礎(chǔ)知識(shí),希望能幫助那些基礎(chǔ)不太好的同行們。加油~~~~~~

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 新手怎么學(xué)JS?JavaScript基礎(chǔ)語(yǔ)法入門(mén)要學(xué)什么?

    這篇文章主要介紹了新手怎么學(xué)JS?JavaScript基礎(chǔ)語(yǔ)法入門(mén)要學(xué)什么?本文給大家介紹一個(gè)大致的學(xué)習(xí)路線(xiàn)和方向,需要的朋友趕緊一起來(lái)看看吧
    2020-03-19
  • 深入理解javascript作用域,作用域鏈,閉包的面試題

    這篇文章主要介紹了javascript作用域,作用域鏈,閉包的面試題,在一些前端面試中經(jīng)常會(huì)問(wèn)題,今天小編特此整理分享到腳本之家平臺(tái),需要的朋友可以參考下
    2020-02-21
  • JavaScript關(guān)于數(shù)組的四道面試題

    這篇文章主要介紹了JavaScript關(guān)于數(shù)組的四道面試題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)
    2019-12-23
  • 11道JS選擇題(聽(tīng)說(shuō)第一題就難倒80%的人)

    這篇文章主要介紹了11道JS選擇題(聽(tīng)說(shuō)第一題就難倒80%的人),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-12-18
  • 10個(gè)比較流行的JavaScript面試題

    JS 初學(xué)者總是對(duì)this關(guān)鍵字感到困惑,因?yàn)榕c其他現(xiàn)代編程語(yǔ)言相比,JS 中的這this關(guān)鍵字有點(diǎn)棘手。今天小編給大家?guī)?lái)10個(gè)比較流行的JavaScript面試題 ,感興趣的朋友一起
    2019-07-12
  • 10個(gè)JavaScript筆試題解析

    這篇文章主要介紹了10個(gè)JavaScript筆試題解析,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2020-06-02

最新評(píng)論