は呼び出しの実装をシミュレートするためですが、なぜ文字列をプッシュしてから次に eval を使用する必要があるのでしょうか? argument[i] を直接渡してから context.fn(args) を使用してみてはいかがでしょうか?
认证高级PHP讲师
ここでは、call的原理,这里我简要还是说明一下原理,我也是参考JavaScript権威あるガイドの指示も理解し、それをコードで実装したと思います。
call
JavaScript
まず、中国語版の ECMAScript 仕様から、call の構文と定義を見てみましょう:
簡単な例を挙げてみましょう:
次に、callを使用した後の出力を見てください:
栗に基づいて以下の質問に答えます:
は call的实现,请问为什么要push一个字符串,下面再用eval?直接传入arguments[i],然后下面用context.fn(args) の実装をシミュレートするためです。なぜ文字列をプッシュして次に eval を使用する必要があるのでしょうか? arguments[i] を直接渡してから、context.fn(args) を使用するのはなぜでしょうか?
eva
arguments[i]
context.fn(args)
まず第一に、上でシミュレートした関数とチェストナット内の変数の間の関係を理解する必要があります:
このステップに注目してください。jawil.sayHello的引用地址给了lulin.sayHello
jawil.sayHello
lulin.sayHello
判明しましたjawil.sayHello.call(context,arg1,arg2,arg3,arg4)
jawil.sayHello.call(context,arg1,arg2,arg3,arg4)
自分の道を切り開いてくださいcontext得到args=[arg1,arg2,arg3,arg4]
context
args=[arg1,arg2,arg3,arg4]
それでは、lulin.sayHello([arg1,arg2,arg3,arg4])を実行してください。はは、とてもわかりにくいですよね。見た目は問題ありませんが、実際には 4 つのパラメータがあり、それらが 1 つの配列に結合され、1 つの配列パラメータになっていることがわかります。ここに問題があります。
lulin.sayHello([arg1,arg2,arg3,arg4])
それでは、この問題をどのように解決するのでしょうか? 考え方は上記の通り、すべてのパラメータを文字列に入れてから eval を使用して実行します。
eval
必要なエフェクトは lulin.sayHello(arg1,arg2,arg3,arg4) です。lulin.sayHello はパラメータを再編成する必要があるため、パラメータを取得することはできませんlulin.sayHello(arg1,arg2,arg3,arg4)这样的,因为lulin.sayHello要重组参数,你不能拿到一个参数执行一次函数吧,或者把参数存到一起一次执行吧,唯一的想到的做法就是把所有参数拼成字符串,然后用evalパラメータを指定して関数を 1 回実行する
lulin.sayHello(arg1,arg2,arg3,arg4)
唯一の方法は、すべてのパラメータを文字列に入れてから lulin.sayHello([arg1,arg2,arg3,arg4]),也不是lulin.sayHello(arg1),lulin.sayHello(arg2) を使用して実行することです。
lulin.sayHello(arg1)
lulin.sayHello(arg2)
や lulin.sayHello(arg1)、lulin.sayHello ではなく、私たちが望む方法です。 (arg2)...
lulin.sayHello ではなく、私たちが望む方法です。 (arg2)
eval とは何ですか? ここでは、何も知らないことにして簡単に説明します。 eval 関数
eval() 関数は文字列を計算し、その中の JavaScript コードを実行できます。
文法:eval(string)
eval(string)
文字列が必要です。評価する JavaScript 式または実行するステートメントを含む、評価する文字列。このメソッドはパラメータとして生の文字列のみを受け入れます。文字列パラメータが生の文字列でない場合、メソッドは変更されずに戻ります。したがって、String オブジェクトを引数として eval() 関数に渡さないでください。 🎜
簡単に言うと、JavaScript の解析エンジンを使用してこの文字列の内容を解析します。eval看成是<script> タグを付けると、このように理解できます。
<script>
これに相当します
さて、上記のコードをもう一度見てみましょう。実際、モーダルの直感的な観点から見てみましょう。以下は完全なデバッグ コードです:
args の出力を見てください:
["引数[1]", "引数[2]"]
次に、「context.fn(' + args + ')」の出力を見てください:
「context.fn(arguments[1],arguments[2])」ちょっとややこしくないですか
実際、ここには暗黙的な変換が含まれています:
'jawil'+[1,2]+[3,4]+3 は何に等しいですか? 'jawil'+[1,2]+[3,4]+3等于多少?等于"jawil1,23,43"其实这个相当于'jawil'+[1,2].toString()+[3,4].toString()+3"jawil1,23,43" と同等
'jawil'+[1,2]+[3,4]+3
"jawil1,23,43"
'jawil'+[1,2].toString()+[3,4].toString()+3
'jawil'+[1,2].toString()+[3,4].toString( )+3 スペースが限られているため、暗黙的な変換の詳細については、私の記事を参照してください: From ++[[]][+[]]+[+[]]==10? 弱い型付けでの暗黙的な変換の詳細な説明JS これについては、あなた自身が理解できることをすべて述べましたが、おそらくスペースが限られているため、明確に説明されていないことがたくさんあります。非常に短い段落のように見えますが、実際には多くの知識ポイントが含まれています。 🎜
args は配列であり、context.fn(args) にはパラメータが 1 つだけあります。通常の状況では、apply を使用して配列をパラメータに変換できますが、ここでは呼び出しをシミュレートするために apply を使用することは無意味です。したがって、配列の toString() を使用して context 以外のパラメータを context.fn に移動します。
arguments[0] は context なので ループ変数が 1 から始まるのがわかりませんでしたか?
ここでは、
call
的原理,这里我简要还是说明一下原理,我也是参考JavaScript
権威あるガイドの指示も理解し、それをコードで実装したと思います。まず、中国語版の ECMAScript 仕様から、
call
の構文と定義を見てみましょう:簡単な例を挙げてみましょう:
リーリー次に、
リーリーcall
を使用した後の出力を見てください:栗に基づいて以下の質問に答えます:
まず第一に、上でシミュレートした関数とチェストナット内の変数の間の関係を理解する必要があります:
リーリーこのステップに注目してください。
を入れただけですjawil.sayHello
的引用地址给了lulin.sayHello
判明しました
jawil.sayHello.call(context,arg1,arg2,arg3,arg4)
自分の道を切り開いてください
context
得到args=[arg1,arg2,arg3,arg4]
それでは、
lulin.sayHello([arg1,arg2,arg3,arg4])
を実行してください。はは、とてもわかりにくいですよね。見た目は問題ありませんが、実際には 4 つのパラメータがあり、それらが 1 つの配列に結合され、1 つの配列パラメータになっていることがわかります。ここに問題があります。それでは、この問題をどのように解決するのでしょうか? 考え方は上記の通り、すべてのパラメータを文字列に入れてから
eval
を使用して実行します。必要なエフェクトは
か、パラメータをまとめて保存して 1 回実行するlulin.sayHello(arg1,arg2,arg3,arg4)
です。lulin.sayHello
はパラメータを再編成する必要があるため、パラメータを取得することはできませんlulin.sayHello(arg1,arg2,arg3,arg4)
这样的,因为lulin.sayHello
要重组参数,你不能拿到一个参数执行一次函数吧,或者把参数存到一起一次执行吧,唯一的想到的做法就是把所有参数拼成字符串,然后用eval
パラメータを指定して関数を 1 回実行する唯一の方法は、すべてのパラメータを文字列に入れてから
これと同様: "lulin.sayHello(arg1,arg2,arg3,arg4)" これは、lulin.sayHello([arg1,arg2,arg3,arg4])
,也不是lulin.sayHello(arg1)
,lulin.sayHello(arg2)
を使用して実行することです。や
lulin.sayHello(arg1)
、lulin.sayHello ではなく、私たちが望む方法です。 (arg2)
...eval とは何ですか? ここでは、何も知らないことにして簡単に説明します。
の定義と使用法を簡単に見てみましょうeval
関数
文法:
eval(string)
簡単に言うと、JavaScript の解析エンジンを使用してこの文字列の内容を解析します。
リーリーeval
看成是<script>
タグを付けると、このように理解できます。これに相当します
リーリーさて、上記のコードをもう一度見てみましょう。実際、モーダルの直感的な観点から見てみましょう。以下は完全なデバッグ コードです:
リーリーargs の出力を見てください:
["引数[1]", "引数[2]"]
次に、「context.fn(' + args + ')」の出力を見てください:
「context.fn(arguments[1],arguments[2])」ちょっとややこしくないですか
実際、ここには暗黙的な変換が含まれています:
実際、これは'jawil'+[1,2]+[3,4]+3
は何に等しいですか?'jawil'+[1,2]+[3,4]+3
等于多少?等于
"jawil1,23,43"
其实这个相当于
'jawil'+[1,2].toString()+[3,4].toString()+3
"jawil1,23,43"
と同等'jawil'+[1,2].toString()+[3,4].toString( )+3
スペースが限られているため、暗黙的な変換の詳細については、私の記事を参照してください: From ++[[]][+[]]+[+[]]==10? 弱い型付けでの暗黙的な変換の詳細な説明JS
これについては、あなた自身が理解できることをすべて述べましたが、おそらくスペースが限られているため、明確に説明されていないことがたくさんあります。非常に短い段落のように見えますが、実際には多くの知識ポイントが含まれています。 🎜
args は配列であり、
context.fn(args)
にはパラメータが 1 つだけあります。通常の状況では、apply を使用して配列をパラメータに変換できますが、ここでは呼び出しをシミュレートするために apply を使用することは無意味です。したがって、配列の toString() を使用して context 以外のパラメータを context.fn に移動します。arguments[0] は context なので
ループ変数が 1 から始まるのがわかりませんでしたか?