call 関数と apply 関数は、一部の単純な Javascript 操作ではほとんど使用されません。Web アプリケーション開発や JS フレームワーク開発など、他の大規模な操作では、これら 2 つの関数が頻繁に使用されることがあります。これら 2 つの機能の説明についてはインターネット上にたくさんの情報がありますが、多くの情報はスクリプト化されているか、非常に類似していて、現実的な説明が欠けていると思います。次に、これら 2 つの機能をより明確かつ簡単な方法で分析して説明しようとします。
まず呼び出しを分析しましょう。これは ECMAScript 3rd Edition の呼び出し関数の説明です [2]: call メソッドが関数オブジェクト (func.call(0)) によって呼び出されるとき、必要なパラメーターといくつかのオプションのパラメーター、その実行プロセスは次のとおりです:
a、オブジェクト呼び出し呼び出しが実行可能でない場合は、TypeError をスローします。
b、パラメータリストを空に設定します
c. 呼び出されたメソッドが複数のパラメーターを渡す場合は、arg1、arg2... をパラメーター リストに
の順序で挿入します。
d. call を呼び出した関数の結果を返し、呼び出し関数 (func) 内のこれを渡されたパラメーター 1 に置き換え、渡されたパラメーター リストをこの関数のパラメーターとして使用します。
実際、call 関数は関数オブジェクトのプロトタイプです。つまり、この呼び出しを呼び出す関数も関数でなければなりません。呼び出しを呼び出す関数内のこれをオブジェクトに置き換えるだけです。渡されました。以下に例を示します:
<script> function C1(){ this.name='张三'; this.age='24'; this.sayname=function(){ console.log("这里是C1类,我的名字是:"+this.name+"我的年龄是"+this.age); } } function C2(){ this.name='李四'; this.age='25'; } var c1=new C1(); var c2=new C2(); c1.sayname(); c1.sayname.call(c2); </script>
実行結果:
これはカテゴリ C1 です。私の名前は Zhang San、年齢は 24 です
これはカテゴリ C1 です。私の名前は Li Si、年齢は 25 です
上記のコードでは、C1 と C2 の 2 つのクラスが宣言されています。C1 には 2 つの属性があり、C2 にも C1 と同じ 2 つの属性があります。c1.sayname() は実際の属性 c1 .sayname を出力します。 call(c2) は c2 の属性のみを出力します。これはなぜでしょうか。 Sayname() は関数であり、関数本体にこれがあるため、呼び出しが実行されると、これは c2 に置き換えられ、最終的には c2 の属性が出力されます。
apply と call の違いは、apply のすべてのオプション パラメータは配列に格納され、1 つのパラメータとして渡されるのに対し、call は複数のパラメータに分割されて渡されます。
それでは、apply 関数と call 関数はどのような用途に使えるのでしょうか? 1 つ目は、Math.max.apply(null,array) を使用して、インターネット上の古典的な方法です。もう 1 つは、次のように apply と call を使用して継承を実装します。 🎜>
<script> function Human(name,sex){ this.name=name; this.sex=sex; this.walk=function(){ console.log('我在走路'); } } function Child(){ Human.call(this,"小明","男") this.paly=function(){ console.log('我很喜欢玩耍'); } this.intruduce=function(){ console.log('大家好,我是'+this.name); } } var jinp=new Human('Jack','男'); var xiaoping=new Child(); xiaoping.walk(); xiaoping.paly(); xiaoping.intruduce(); </script>
歩いています
私は遊ぶのがとても好きです
皆さんこんにちは、シャオミンです
call() および apply() に似た関数は binding() です。これは ECMAScript 5 の新しいメソッドですが、bind() は ECMAScript 3 で簡単にシミュレートできます。バインド関数も、JavaScript の Function.prototype のメソッドです。このメソッドの主な内容は、関数をオブジェクトにバインドすることです。 bind() メソッドが関数 f() にバインドされ、オブジェクト o がパラメータとして渡されると、このメソッドは o のメソッドとして呼び出される新しい関数を返します。新しい関数に渡された引数はすべて、元の関数に渡されます。以下のように:
<script> function introduce(country,hobby){ return "大家好,我叫"+this.name+", 今年"+this.age+"岁, 来自"+country+", 喜欢"+hobby; } var xiaoming={name:"小明",age:20} var jieshao=introduce.bind(xiaoming); console.log(jieshao("中国","打球")); </script>
みなさん、こんにちは。私の名前はシャオミンです。20歳、中国出身、ボール遊びが好きです
上記の例は次と同等です:
<script> function introduce(country,hobby){ return "大家好,我叫"+this.name+", 今年"+this.age+"岁, 来自"+country+", 喜欢"+hobby; } var xiaoming={name:"小明",age:20} console.log(introduce.apply(xiaoming,["中国","打球"])); //或者下面这个 console.log(introduce.call(xiaoming,"中国","打球")); </script>
参考資料
[1]、JavaScript 第 6 版決定版ガイド、189 ページ
[2]、
Function.prototype.call (thisArg [ , arg1 [ , arg2, … ] ] )
[3]、
Function.prototype.apply (thisArg, argArray)