jsで関数を転送する方法

不言
リリース: 2018-07-16 16:02:17
オリジナル
1864 人が閲覧しました

最近jsを勉強する過程で、js関数のパラメータとしてオブジェクトを渡す問題に遭遇しました。 時間はかかりましたが、ようやく理解できました。

データ型

JavaScript のデータ型は 2 つのカテゴリに分類できます:

基本型値、プリミティブ型 (未定義、Null、ブール、数値、文字列など)。

参照型の値、つまりオブジェクト型 オブジェクト、配列、関数、日付などのオブジェクト型。

変数のコピー

ご存知のとおり、js の変数の基本型と参照型は異なる方法で保存されており、コピーすると変数も異なります。基本型の値をある変数から別の変数にコピーすると、前の値が複製され、複製された値が後者に割り当てられます。したがって、2 つの値は完全に独立していますが、それらの値は異なります。同じ。

var num1 = 10;var num2 = num1;
console.log(num2);//10
ログイン後にコピー

上記のnum1に保存されている値は10です。num1の値をnum2に代入すると、num2の値も10になります。ただし、これら 2 つの 10 は完全に独立しています。これは、Word 文書を作成して num1 のフォルダーにコピーすることと同じです。このコピーを num2 のフォルダーに置きます。2 つの Word ドキュメントはまったく同じであり、どちらかを変更しても両方には影響しません。

num2 += 1;
console.log(num1); //10
console.log(num2); //11
ログイン後にコピー

上記からわかるように、num2 の値は変更されていますが、num1 の値は変更されていません。参照型のコピーを見てみましょう。参照型の値をある変数から別の変数にコピーすると、変数オブジェクトに格納されている値のコピーも、新しい変数に割り当てられた領域にコピーされます。

var obj1 = {
  name : "111"};var obj2 = obj1;
console.log(obj2.name); //111
obj2.name = "222";
console.log(obj1.name); //222
ログイン後にコピー

最初の印刷結果は「111」でわかりやすいですが、2番目の印刷結果は「222」で少しわかりません。これが参照型と基本型の違いです。オブジェクトをコピーする場合、同一のオブジェクトはヒープ メモリ内に作成されず、オブジェクトへのポインタを保持する追加の変数が作成されるだけです。 obj1 の値を obj2 にコピーします。この値のコピーは実際にはポインタであり、ヒープに格納されているオブジェクトを指します。つまり、新しいメモリ アドレスが作成され、obj2、obj1、および obj2 に渡されます。変数は同時に同じオブジェクトを指します。オブジェクトが変更されると、それらの値が変化します。つまり、いずれか 1 つによる変更がもう 1 つにも反映されます。以下の簡略図の方がわかりやすいかもしれません。

関数パラメータの転送

「JS 高度なプログラミング」では、パラメータ転送について次のように説明されています。 すべての関数パラメータは値によって渡されます。つまり、関数の外部の値は関数内のパラメータにコピーされます。ある変数から別の変数に値をコピーすることと同じです。したがって、変数のコピーを理解できれば、パラメータの受け渡しは非常に簡単になります。基本的なタイプの例から始めましょう。

var count = 10;function num(num1){
   num1 = 1;
   return num1;
}var result = num(count);console.log(result);//1
console.log(count);//10,并未变成1
ログイン後にコピー

この例は、実際に count のコピーを作成し、その後 count の値をパラメーターに渡します。パラメーターの値は 1 で 10 を上書きし、最終的な結果が返されます。 1 ですが、カウントは変更されていません。オブジェクトを渡す例を見てみましょう。

var person  = {
    name : "Tom"};function obj(peo){
    peo.name = "Jerry";
    return peo;
}var result = obj(person);
console.log(result.name);// Jerry
console.log(person.name);// Jerry
ログイン後にコピー

上記の例では、person がコピーされて obj() に渡され、peo と person は同じオブジェクトを指しており、実際には、それらが共同で指すオブジェクトの name 属性が変更されています。それに応じて、対応する外部の人が参照する name 属性も変更されるため、出力されるのは Jerry です。実際、一見すると、参照型パラメータは参照によって渡されているように見えますが、これは私が最初に犯した間違いでした。別の例を見てみましょう。

var person = {
    
name : "Tom"}; 
 function obj(peo){
    
peo = {
      
 name : "Jerry"
    };    
return peo; 
}
var result = obj(person);console.log(result.name);// Jerry

console.log(person.name);// Tom
ログイン後にコピー

上の例では、オブジェクトが関数内で再定義されています。つまり、ヒープ メモリ内に 2 つのオブジェクトが存在し、外部の人は古いオブジェクトを指し、渡されたパラメータは新しく定義されたオブジェクトを指します。 . オブジェクトなので、呼び出し後に返される値は新しく定義されたオブジェクトの値です。パラメータが参照によって渡される場合、person.name の出力結果は Jerry になります。この時点から、パラメータは値によって渡されると結論付けることができます (共有によって渡されると呼ぶところもあります)。

老羅推奨の『人類概史』を参考に視覚化しましたが、描写があまり良くありません。略歴の第一章のタイトルを「人物」に変更しました。後ろのページ数に応じて、「認知革命」の内容、つまり「対象」が直接わかります。 2 番目の章は「農業革命」で、これを「結果」と呼びます。そのサブディレクトリには「メモリ過負荷」セクションがあります (「peo」に名前変更されました)。このセクションの内容を直接見つけることもできます。ページ番号に基づいて。ここで、「人」を「個人」にコピーすると、第 2 章の「個人」のセクションが「人」になり、第 1 章の「個人」に基づいて見つかったものは、依然として第 1 章の内容のままです。異なるコンテンツセクションに移動し、相互に干渉しません。ここで、ヒープ メモリは各章の内容であり、第 1 章と第 2 章の内容は 2 つの異なるオブジェクトであり、この 2 つは互いに無関係であるため、外部の person.name を出力すると、結果は前のオブジェクトのままになります。属性値。

結論

要するに、js のパラメーターは値によって渡されます。私が書いた例は少し大まかですが、「JavaScript 高度なプログラミング」の例はより明確で理解しやすいです。

関連する推奨事項:

js における関数パラメータの実装原理

js 関数の実パラメータ、仮パラメータ、クロージャの理解

以上がjsで関数を転送する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート