apply()の実装

一緒に書く習慣を身につけましょう!「ナゲッツデイリーニュープラン・4月アップデートチャレンジ」に参加して9日目です。クリックしてイベントの詳細をご覧ください

序文

昨日、call()の実装を手作業で作成しました。リンクをクリックすると、特定のコンテンツを表示できます。今日は、apply()の実装を作成して、記憶を深めます。

apply()およびcall()

apply()を作成する前に、applyとcallの関係について説明する必要がありますが、どちらにも類似点と相違点があります。

  • 共通点
  1. 彼らは両方ともこれのポイントを変えることができます
  2. ターゲット関数にパラメータを渡すことができます
  • 違い
  1. それらのパラメータ形式は異なります

上記の相違点と類似点に基づいて、applyの手書きコードとcallの手書きコードの主な違いは、渡されたパラメーターの処理にあるはずであるという結論を簡単に引き出すことができます。まず最初に、そのパラメーターの数を指定したので、引数を使用する必要はありません。以下のコードを参照してください

    Function.prototype.myApply= function(context,arr){
            context = context || window
            context.fn = this
            var result;
            if(!arr){
                result = context.fn()
            }else{
                var args = []
                for(var i=0;i<arr.length;i++){
                    args.push(arr[i])
                }
                result = context.fn(...args)
            }
            delete context.fn
            return result
        }
复制代码

注:上記のコードは、es6でspread演算子を直接使用しています。es6のものを使用しない必要がある場合は、呼び出しの実装のようにeval()関数を使用することもできます(eval('context.fn(' + args + ')'))。以下でテストして、問題がないかどうかを確認してください。最初に、これのポインティングが変更されたかどうかをテストします

 animal = {color:'yellow'}
        function dog(){
            console.log(this.color)
        }
        console.log(dog.myApply(animal))
复制代码

結果は次のとおりです。

image.png

この点は正常に変更されました。パラメータの受け渡しに問題があるかどうかをテストしてみましょう。

animal = {color:'yellow'}
        function dog(name,age){
            
            console.log(this.color)
            console.log(name)
            console.log(age)
            return {
                name:name,
                age,age,
                color:this.color
            }
        }
        console.log(dog.myApply(animal,['小白',6]))
复制代码

結果は次のとおりです。

image.png

渡されたパラメータは正常に出力され、applyの主な機能が基本的に実現されていることを示しています。

要約する

call()とapply()の実装ロジックは実際には似ていますが、主な違いは、使用する場合のパラメーターのタイプと数です。しかし実際には、上記の実装にはまだいくつかの問題があります。

  1. コードのfnは、コンテキストにこのプロパティがないことを前提としています。コンテキストにすでにこのプロパティがある場合は、問題が発生します(ここでの解決策はvar fn = Symbol()を使用できます)が、次の機能を使用します。 es6、このように使用したくない場合は、乱数とfnの組み合わせを記述し、コンテキストにこのフィールドが含まれているかどうかを判断します。含まれている場合は、この属性がなくなるまで再生成されます。

2.着信コンテキストはオブジェクトではない可能性があります(文字列などの基本的なデータ型にすることができます)。現時点では、コンテキストを処理する必要がありますcontext= Object(context) || window。これで完璧です。

おすすめ

転載: juejin.im/post/7086742049067630606