javascript - jsでのcallメソッドの実装
PHP中文网
PHP中文网 2017-06-12 09:30:07
0
3
836
リーリー

は呼び出しの実装をシミュレートするためですが、なぜ文字列をプッシュしてから次に eval を使用する必要があるのでしょうか? argument[i] を直接渡してから context.fn(args) を使用してみてはいかがでしょうか?

PHP中文网
PHP中文网

认证高级PHP讲师

全員に返信(3)
给我你的怀抱

ここでは、call的原理,这里我简要还是说明一下原理,我也是参考JavaScript権威あるガイドの指示も理解し、それをコードで実装したと思います。

まず、中国語版の ECMAScript 仕様から、call の構文と定義を見てみましょう:

簡単な例を挙げてみましょう:

リーリー

次に、callを使用した後の出力を見てください:

リーリー

栗に基づいて以下の質問に答えます:

call的实现,请问为什么要push一个字符串,下面再用eval?直接传入arguments[i],然后下面用context.fn(args) の実装をシミュレートするためです。なぜ文字列をプッシュして次に eval を使用する必要があるのでしょうか? arguments[i] を直接渡してから、context.fn(args) を使用するのはなぜでしょうか?

まず第一に、上でシミュレートした関数とチェストナット内の変数の間の関係を理解する必要があります:

リーリー

このステップに注目してください。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 を使用して実行します。

必要なエフェクトは lulin.sayHello(arg1,arg2,arg3,arg4) です。lulin.sayHello はパラメータを再編成する必要があるため、パラメータを取得することはできませんlulin.sayHello(arg1,arg2,arg3,arg4)这样的,因为lulin.sayHello要重组参数,你不能拿到一个参数执行一次函数吧,或者把参数存到一起一次执行吧,唯一的想到的做法就是把所有参数拼成字符串,然后用evalパラメータを指定して関数を 1 回実行する

か、パラメータをまとめて保存して 1 回実行する

唯一の方法は、すべてのパラメータを文字列に入れてから lulin.sayHello([arg1,arg2,arg3,arg4]),也不是lulin.sayHello(arg1),lulin.sayHello(arg2) を使用して実行することです。

これと同様: "lulin.sayHello(arg1,arg2,arg3,arg4)" これは、

lulin.sayHello(arg1)lulin.sayHello ではなく、私たちが望む方法です。 (arg2)...

eval とは何ですか? ここでは、何も知らないことにして簡単に説明します。 eval
関数

の定義と使用法を簡単に見てみましょう

eval() 関数は文字列を計算し、その中の JavaScript コードを実行できます。


文法:eval(string)

文字列が必要です。評価する JavaScript 式または実行するステートメントを含む、評価する文字列。このメソッドはパラメータとして生の文字列のみを受け入れます。文字列パラメータが生の文字列でない場合、メソッドは変更されずに戻ります。したがって、String オブジェクトを引数として eval() 関数に渡さないでください。 🎜

簡単に言うと、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

これについては、あなた自身が理解できることをすべて述べましたが、おそらくスペースが限られているため、明確に説明されていないことがたくさんあります。非常に短い段落のように見えますが、実際には多くの知識ポイントが含まれています。 🎜
いいねを押す +0
曾经蜡笔没有小新

args は配列であり、context.fn(args) にはパラメータが 1 つだけあります。通常の状況では、apply を使用して配列をパラメータに変換できますが、ここでは呼び出しをシミュレートするために apply を使用することは無意味です。したがって、配列の toString() を使用して context 以外のパラメータを context.fn に移動します。

いいねを押す +0
淡淡烟草味

arguments[0] は context なので
ループ変数が 1 から始まるのがわかりませんでしたか?

いいねを押す +0
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート