フロントエンドP 5が最も基本的に把握すべきコード実装

4519 ワード

前景
昨年、インターネットの一連の波紋を経験した後、多くのパートナーが今年の金三銀四の面接シーズンで自分の未来のために良い会社を探していると信じています.では、今日はP 5エンジニアのために知っておくべき原理と、どのように自分で手書きで実現するかを説明します.私たちが日常的に業務を開発するときに自分で書く方法が使えないかもしれませんが、私たちは原理について何も知らないので、面接の時に深く掘られると、自分の考えている会社からまた一歩遠ざかる可能性があります.

モードcall

  • の最初のパラメータがnullまたはundefinedの場合、thisはグローバルオブジェクトwindowを指し、値が元の値の場合はString、number、boolean
  • などの元の値を変更する自動パッケージオブジェクトを指す.
  • 関数名が上下の質問(context)の属性と衝突しないようにSymbolタイプを一意の値
  • として使用する.
  • 関数を入力コンテキスト属性として
  • を実行する.
  • 関数の実行後に属性変更
  • を削除する.
  • は、実行結果
  • を返す.
    Function.prototype.myCall = function(context,...args){
        context = (context ?? window) || new Object(context);
        const key = Symbol();
        context[key] = this;
        const result = context[key](...args);
        delete context[key];
        return result;
    }

    モードapply

  • 前部分はcallと同じ
  • の2番目のパラメータは送信されなくてもよいが、タイプは配列またはクラス配列
  • でなければならない.
    Function.prototype.myApply = function(context) {
        context =  (context ?? window) || new Object(context)
        const key = Symbol()
        const args = arguments[1]
        context[key] = this
        let result
        if(args) {
            result = context[key](...args)
        } else {
            result = context[key]
        }
        delete context[key]
        return result
    }

    モードbind

  • call/applyを使用してthis
  • を指定
  • は、バインド関数
  • を返す.
  • 返されたバインド関数が構造関数としてnewによって呼び出されると、バインドコンテキストはインスタンスオブジェクト
  • を指す.
  • バインド関数を設定するprototypeは元の関数のprototype
  • である.
    Function.prototype.myBind = function(context, ...args) {
        const fn = this
        const bindFn = function (...newFnArgs) {
            fn.call(
                this instanceof bindFn ? this : context,
                ...args, ...newFnArgs
            )
        }
        bindFn.prototype = Object.create(fn.prototype)
        return bindFn
    }

    深いコピー

  • は、タイプが元のタイプであるか否かを判断し、もしそうであれば、コピーを必要とせずに
  • に戻る.
  • ループ参照を回避するために、オブジェクトをコピーする際に、まず記憶領域に現在のオブジェクトが存在するか否かを判断し、存在する場合は
  • に戻る.
  • は、現在のオブジェクトとコピーオブジェクトとの対応関係
  • を記憶する記憶空間を開く.
  • は、属性が元のタイプである
  • まで参照タイプを再帰的にコピーする.
    const deepClone = (target, cache = new WeakMap()) => {
        if(target === null || typeof target !== 'object') {
            return target
        }
        if(cache.get(target)) {
            return target
        }
        const copy = Array.isArray(target) ? [] : {}
        cache.set(target, copy)
        Object.keys(target).forEach(key => copy[key] = deepClone(obj[key], cache))
        return copy
    }

    関数ジッタ防止

  • thisは親コンテキストから継承され、トリガイベントのターゲット要素
  • を指す.
  • イベントがトリガーするとeventオブジェクト
  • に転送される.
  • はleadingパラメータを入力し、直ちにコールバック関数を実行できるかどうかを判断し、イベント停止トリガを待ってから
  • を実行する必要はない.
  • コールバック関数には、実行結果
  • を返す必要がある戻り値がある.
    const debounce = (fn, wait = 300, leading = true) => {
        let timerId, result
        return function(...args) {
            timerId && clearTimeout(timerId)
            if (leading) {
                if (!timerId) result = fn.apply(this, args)
                timerId = setTimeout(() => timerId = null, wait)
            } else {
                timerId = setTimeout(() => result = fn.apply(this, args), wait)
            }
            return result
        }
    }

    かんすうオリフィス

            n      ,             
    const throttle = (fn, wait = 300) => {
        let timerId
        return function(...args) {
            if(!timerId) {
                timerId = setTimeout(() => {
                    timerId = null
                    return result = fn.apply(this, ...args)
                }, wait)
            }
        }
    }

    関数スロットル(タイムスタンプ)


    関数がトリガーされるとすぐに実行され、トリガーが停止するとイベントは実行されません.
    const throttle = (fn, wait = 300) => {
        let prev = 0
        let result
        return function(...args) {
            let now = +new Date()
            if(now - prev > wait) {
                prev = now
                return result = fn.apply(this, ...args)
            }
        }
    }

    ES 6版継承


    ES 5の継承は,実質的にサブクラスのインスタンスオブジェクトを作成してから親クラスのメソッドをthisに追加する.ES 6の継承は、親クラスのインスタンスオブジェクトを作成する(したがって、superメソッドを呼び出してから、サブクラスのコンストラクション関数でthisを変更する必要があります.
    class Super {    constructor(foo) {      this.foo = foo    }    printFoo() {      console.log(this.foo)    }  }       class Sub extends Super {    constructor(foo, bar) {      super(foo)      this.bar = bar    }  }js

    上の部分はすべて1つのP 5として基本的な技能を持つべきで、同时に私のこちらは続々といくつかの列の面接问题を更新することができて、call、apply、bindに対して何がはっきりしない地方が私の前の文章を见て、あなたに1篇の文章を彻底的にはっきりさせて、ここでES 6が継承すると言って、それから私は対象向けのプログラミングと设计のモードを结び付けて顺次みんなに说明します注目tu先生はフロントエンドがあなたを連れてスタックを回ると言った.