コール、適用し、バインドし、その差を使用して - 研究ノート

 

ほとんどJSコールについて尋ねたびにそれらをインタビュー、適用する、などの問題、のバインド...

  • 呼び出しを使用する方法、配列の最大値または最小値を見つけるために適用されます
  • 継承を行うには、呼び出しを使用して適用する方法
  • 、コール、バインドの違いや、主要なアプリケーションシナリオを適用

まず、我々は、これらの3つの機能の存在の意味が何であるかを理解する必要がありますか?

:答えは関数が実行されるコンテキストを変更し、その後、具体的な点は、実行時関数のこのポイントを変更します

このような理解では、我々はこれらの3つの機能を使用する方法を、見てください。

せOBJ = {名: 'トニー' };
  
  関数子(名前){
     この .nameの= 名前。
  }
  
  Child.prototype = {
    コンストラクタ:子供、
    showName:関数(){
      console.log(この.nameの);
    }
  }
  VaRの子= 新しい子( 'トーマス);
  child.showName(); // トーマス
  
  //   呼び出し、適用、バインド使用
  child.showName.call(OBJ)。
  child.showName.apply(OBJ)。
  バインドLET = child.showName.bind(OBJ); //はの機能を返す 
  バインドを(); // トニー

 

私たちは、他人のshowName方法を取り、動的に多重化を達成するために最終的な分析では、独自の出力コンテキストヘルプ情報を変更されます

練る

バインドメソッドは、この変更の前にある私たちが望むべきでfnを、およびパラメータ値を対応する良い準備、後で使用するために、あなたが実行を指示することができますすることで、そのバインドはまた、この変更を指すことができますが、と適用され、差が直ちに(一例として)コールを実行していません

注:この方法でバインドがIE6〜8の互換性はありません。

違い

上記の3つの機能はほとんどそれが3人を存在している必要がありますなぜ、あなたが滞在することはできません、ほとんど同じことをやって、役割を探します。だから、実際には、彼らは物事の本質は、この文脈で同じダイナミックに変化ありませんが、どのくらいの中にいくつかの違いがあります。..

  • コール、適用およびバインドの違い

呼び出し、関数の実行後にコンテキストを変更するには、この機能を適用し、リターンバインド変更コンテキストの関数です。

  • 差分呼び出し、適用されます

その差は、二つのパラメータ間の差であるコールと最初の引数を適用するオブジェクトコンテキストを変更することで、第二引数からの呼び出しは、パラメータのリストの形で表示するために始めた、それはコンテキストオブジェクトを変更することに加えて適用することですここで2番目の引数としてパラメータ配列。

例1:最も値の配列
ARR1せ= [1、2、19、6 ]。
console.log(Math.max.call(ヌル、1,2,19,6)); // 19 
はconsole.log(Math.max.call(ヌル ARR1の、)); // のNaN 3 
にconsole.log(数学。 max.apply(ヌル、ARR1)); //   19は直接ARR1に移すことができます

例2:
関数FN(){
    console.log(この);
}
// 同じ方法で結果が適用 
)(fn.call; // 通常モードがこの厳密モードでは、ウィンドウでは定義されていません 
fn.call(NULL); // 通常モードこれはウィンドウである、この厳密モードヌルさ 
fn.call(不定); // 通常モードでは、これは、厳密モードでは、これは未定義のウィンドウであります

アプリケーション

  • アレイ(オブジェクト属性を含む長さ、引数、パラメータDOMノード機能)にダミーアレイ

jsが...アレイ(例えばdocument.getElementsByTagNameによって要素を取得し、長さのプロパティは、オブジェクトを含む)の長性を有する、及び添字1、2によってアクセスすることができる要素を擬似が、配列プッシュせず、ポップ他の方法。コールを使用することができ、実際の配列に変換適用するには、配列はこの方法で使用することができます

case1: dom节点:
<DIV CLASS = "DIV1"> 1 </ div>
<DIV CLASS = "DIV1"> 2 </ div>
<DIV CLASS = "DIV1"> 3 </ div>

DIVましょう = document.getElementsByTagName( 'div要素' );
console.log(DIV); // (3)[div.div1、div.div1、div.div1] lengthプロパティのHTMLCollection含ま

LETのARR2は = Array.prototype.slice.call(DIV)。
console.log(ARR2である); // 配列[div.div1、div.div1、div.div1]
 

これはIE6〜8には適用されませんが、エラーが発生します。

SCRIPT5014: Array.prototype.slice: 'this' 不是 JavaScript 对象 (报错)
その後〜8 IE6で1サイクルのみで、アレイに追加することができます。
ためVAR ; I <oLis.length; iが0 = I ++ ){
    【ary.length] = Manolis [I]。
}

IE6〜8と標準的なブラウザ、配列アレイツールに抽出されたオブジェクト間の差に基づいて:
関数listToArray(likeAry){
     VAR進= [];
    してみてください{ = Array.prototype.slice.call(likeAry)。
    } キャッチ(E){
         ためvarが I = 0、I <likeAry.length; I ++ ){
            進[ary.length] = likeAry [I]。
        }
    }
    リターン進。
}

ケース2
:引数の内部は、fn
機能FN10(){
     リターンArray.prototype.slice.call(引数)。
}
console.log(FN10( 1,2,3,4,5))。// [1、2、3、4、5]
 

注:ボローの場合はメソッドの引数配列は、互換性の問題がないということです。

ケース3:オブジェクト属性の長さが含まれています

= OBJ4せ{
     0:1  1:「トーマス 2:13 
    長さ: 3 // lengthプロパティを持っている必要があります
};

console.log(Array.prototype.slice.call(OBJ4))。// [1、 "トーマス"、13]
 
  • ステッチの配列は、追加します
ARR1せ= [1,2,3 ]。
ARR2せ = [4,5,6 ]。

// メソッドの連結配列は:の新しい配列を返し 
ましょうARR3 = arr1.concat(ARR2があります)。
console.log(ARR3); // [1、2 ,. 3 ,. 4 ,. 5 ,. 6] 

(ARR1の)はconsole.log; // [1,2 ,. 3]変更 
(ARR2である)にconsole.logを; // [ 4、5、6]不変
// 使用は方法を適用するには、 
[] .push.apply(ARR1、ARR2である);   // 追加ARR2をARR1するれる 
にconsole.log(ARR1); // [1、2、。3、4、5 、6] 
はconsole.log(ARR2である); // 変更
  • 変数の型を分析します
ARR1せ= [1,2,3 ]。
str1が聞かせて = '文字列' ;
OBJ1せ = {名:「トーマス}。
//
 関数でIsArray(OBJ){
   リターン Object.prototype.toString.call(OBJ)=== '[オブジェクト配列]' 
}
console.log(FN1(ARR1))。// 

//   実施形態の種類を決定し、配列を決定し、(typeof演算ヌルオブジェクトので等しい)は、最も一般的な言語オブジェクト、ヌル   
(Object.prototype.toString.call()ARR1の)はconsole.log; // [配列オブジェクト] 
にconsole.logを( Object.prototype.toString.call(0009)); // [オブジェクトの文字列] 
はconsole.log(Object.prototype.toString.call(OBJ1)); // [オブジェクトのオブジェクト] 
はconsole.log(Object.prototype.toString。コール(ヌル)); // [ヌルオブジェクト]

 

  • コールの使用を作成し、継承を適用​​します
関数動物(名前){      
     この .nameの= 名前。      
    この .showName = 関数(){      
        console.log(この.nameの);      
    }      
}      

関数キャット(名){    
    Animal.call(この、名);    
}      

// Animal.call(この)オブジェクトではなく、動物のオブジェクトのこれを使用することであることを意味し、
// 動物猫のすべてのプロパティとメソッドは、まだ持っていない、猫は、直接動物のオブジェクトのメソッドとプロパティを呼び出すことができます
するvar = CATを新しい新しい猫( "TONY" );     
cat.showName();   // TONY

 

  • 多重継承
  機能クラス1(B){
     この .showclass1 = 関数(a、b)は{
      console.log( `クラス1:$ {}、$ {B}`)。
    }
  }

  機能クラス2(B){
     この .showclass2 = 関数(a、b)は{
      console.log( `クラス2:$ {}、$ {B}`)。
    }
  }

  関数Class3に(A、B、C){
    Class1.call(この);
    Class2.call(この);
  }

  ARR10ましょう = [2,2 ]。
  聞かせてデモ = 新しいClass3に();
  demo.showclass1.call(、1); // クラス1:1、不定 
  demo.showclass1.call(この、1,2)。// クラス1:1,1 
  demo.showclass2.apply(これ、ARR10)。// クラス2:1,2
若以上内容有不妥之处,还望指正,谢谢。

参照します。https://juejin.im/post/5a9640335188257a7924d5ef

 

おすすめ

転載: www.cnblogs.com/cmyoung/p/12006952.html