JavaScriptの関数呼び出しのコード詳細
おそらく多くの人が
JavaScript を学習する過程で 関数パラメータ送信メソッドの混乱に遭遇したことがあると思いますが、JavaScript での関数呼び出しの知識についてのチュートリアルを共有します。興味がある方は、共有してみましょう
定義
おそらく多くの人が、JavaScript を学習する過程で、関数のパラメータの受け渡し方法について混乱に遭遇したことがあると思います。ソース コードでいくつかの答えを見つけますが、その前に、まずいくつかの概念を明確にしてください。値の受け渡し、reference受け渡しなどの固有の名前を放棄して、英語に戻ります:
参照による呼び出し && 値による呼び出し && 共有による呼び出し
は、それぞれ参照の受け渡しと値の受け渡しとして理解されるものです。 C++。 3 番目の説明はさらに混乱します。公式の説明では、オブジェクトへの参照のコピーを受け取ります。分かりやすい言葉で説明しましょう: オブジェクトは
keyのコレクションとして理解できます。オブジェクトは、キーが指すデータを指します (ここでは、それがポインター実装であるか C++ 参照実装であるかについては詳しく説明しません)。 ) 関数が受け取るのは 変数 コピーの場合、変数にはオブジェクトへの参照が含まれており、値によって渡されます。 すると、関数がパラメータを渡すときに受け取る
objecttype パラメータは、実際には実際のパラメータのコピーであることは明らかです。そのため、オブジェクトのキーが変更されているため、type パラメータのポインタを直接変更することは現実的ではありません。それ自体は参照なので、キーを指して変更することが可能です。
証明いくつかの簡単なコードで証明できます
コード 1: 関数は key が指すデータを変更できます
let func = obj => { obj.name = 'Dosk' }; let obj = {name : 'Alxw'}; console.log(obj); //{ name: 'Alxw' } func(obj) console.log(obj); //{ name: 'Dosk' }
コード 2: 関数は obj
let func = obj => { obj = {} }; let obj = {name : 'Alxw'}; console.log(obj); //{ name: 'Alxw' } func(obj) console.log(obj); //{ name: 'Alxw' }
コード 3:内部 obj と外部 = == の結果は等しい
let def = {name : 'Alxw'}; let func = obj => { console.log(obj === def) }; func(def); //true
つまり、3 番目のコードに何か問題がある可能性があります。obj は def のコピーであるのに、なぜ === 演算が true になるのでしょうか。 === 演算はオブジェクトのメモリ内のアドレスを比較するという意味ではないでしょうか。コピーの場合は false になるはずです。
それでは、Google V8 のソースコードに戻ってこれを見てみましょう。
Google V8の詳細ソースコードの厳密に等しいオペレーションコード部分を見てみましょう:
bool Object::StrictEquals(Object* that) { if (this->IsNumber()) { if (!that->IsNumber()) return false; return NumberEquals(this, that); } else if (this->IsString()) { if (!that->IsString()) return false; return String::cast(this)->Equals(String::cast(that)); } else if (this->IsSimd128Value()) { if (!that->IsSimd128Value()) return false; return Simd128Value::cast(this)->Equals(Simd128Value::cast(that)); } return this == that; }
理論的には、defとobjが異なる場合は最後のケースであるはずです。オブジェクトの場合は false が返されるはずです。そうです。これは上記の内容を覆しませんか?実は、いいえ、無視されていることが 1 つあります。つまり、オブジェクトを内部でインスタンス化する場合、Google V8 自体は動的インスタンス化であり、コンパイル言語では動的インスタンス化はヒープ メモリ上でのみ実行できる、つまりポインタのみが実行できることがわかっています。引用します。この結論の証明には Local や Han
dle などの class の実装が必要になるので、簡単な証明方法としては、< の呼び出しをすべて取得する search という方法があります。 code>Object::StrictEquals Code> は、アドレス取得操作なしで直接渡されます。
しかし、値によって渡される変数には Object への参照が含まれているため、理論的には Object も変更できるのに、なぜ 3 番目のコードを変更できないのかと疑問に思う人もいるかもしれません。 Object::StrictEquals
的地方都是直接传入而没有取地址操作。
不过有人会问,既然是值传递的变量包含 Object 的引用,理论上也能够修改 Object 才对,为什么第三段代码不能修改呢?
很简单的道理,因为我们在 Javascript 语言逻辑层次上的所谓的操作,只不过是在调用 Google V8 的实例方的法而已,根本不可能操作到这一地步(当然,潜在的 BUG 不算的 -。-)
重新定义
我觉得到这里可以给 call by sharing 重新解释一下了:
的确,传递的时候是值传递,但是内容包含了 Object 的指针,而且不能够修改这个指针,他是多个变量共享的。
另一种简单的证明
来来来,看源码
V8_DEPRECATE_SOON("Use maybe version", Local<Value> Call(Local<Value> recv, int argc, Local<Value> argv[])); V8_WARN_UNUSED_RESULT MaybeLocal<Value> Call(Local<Context> context, Local<Value> recv, int argc, Local<Value> argv[]);
上面的是即将弃用的接口,碰巧我看到的这个版本代码包含大量的这种即将弃用的代码,看看就好。重点是第二个接口,是函数的唯一的调用的接口。里面的 Local<Value>
最终会调用 C++ 的位复制,所以可以简单的证明就是值传递。
可能是重点
别忘了,我们定义的的变量都是类似 Handle<Object>
再定義
🎜🎜ここで共有することで呼び出しを再説明できると思います:🎜🎜確かに、渡すときは値によって渡されますが、コンテンツにはオブジェクトのポインタが含まれており、 not このポインタは変更でき、複数の変数で共有されます。 🎜🎜🎜🎜もう 1 つの簡単な証明🎜🎜🎜🎜さあ、ソース コードを見てください🎜rrreee🎜上記は、間もなく非推奨になる予定の インターフェース🎜、たまたま私が見たこのバージョンのコードには、廃止予定のコードが多数含まれています。ちょっと見てください。焦点は、関数の唯一の呼び出しインターフェイスである 2 番目のインターフェイスにあります。内部のLocal<Value>
は最終的に C++ のビット コピーを呼び出すため、それが値の転送であることを簡単に証明できます。 🎜🎜🎜🎜おそらくこれが重要なポイントです🎜🎜🎜🎜忘れないでください、私たちが定義する変数はすべて Handle<Object>>
の形式であるため、それらの間のオブジェクトは共有されます。 Javascript の変数は Object のインスタンスを直接参照しません!!!🎜🎜🎜🎜最後のもの🎜🎜🎜要するに、理解しにくい、あるいは間違いが含まれているかもしれませんが、JavaScript 言語レベルで特性を判断できることが重要です。
上記は、編集者があなたに紹介した Javascript の関数呼び出しです。ご質問があれば、メッセージを残してください。編集者がすぐに返信します。スクリプト ハウス Web サイトをサポートしてくださった皆様にも感謝いたします。
以上がJavaScriptの関数呼び出しのコード詳細の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 はじめに: 技術の継続的な発展により、音声認識技術は人工知能の分野の重要な部分になりました。 WebSocket と JavaScript をベースとしたオンライン音声認識システムは、低遅延、リアルタイム、クロスプラットフォームという特徴があり、広く使用されるソリューションとなっています。この記事では、WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法を紹介します。

WebSocketとJavaScript:リアルタイム監視システムを実現するためのキーテクノロジー はじめに: インターネット技術の急速な発展に伴い、リアルタイム監視システムは様々な分野で広く利用されています。リアルタイム監視を実現するための重要なテクノロジーの 1 つは、WebSocket と JavaScript の組み合わせです。この記事では、リアルタイム監視システムにおける WebSocket と JavaScript のアプリケーションを紹介し、コード例を示し、その実装原理を詳しく説明します。 1.WebSocketテクノロジー

JavaScript と WebSocket を使用してリアルタイム オンライン注文システムを実装する方法の紹介: インターネットの普及とテクノロジーの進歩に伴い、ますます多くのレストランがオンライン注文サービスを提供し始めています。リアルタイムのオンライン注文システムを実装するには、JavaScript と WebSocket テクノロジを使用できます。 WebSocket は、TCP プロトコルをベースとした全二重通信プロトコルで、クライアントとサーバー間のリアルタイム双方向通信を実現します。リアルタイムオンラインオーダーシステムにおいて、ユーザーが料理を選択して注文するとき

C++ 関数呼び出しのパフォーマンスの最適化には、パラメーター受け渡し戦略と戻り値の型の最適化という 2 つの側面が含まれます。パラメータの受け渡しに関しては、値の受け渡しは小さなオブジェクトや変更不可能なパラメータに適していますが、参照またはポインタの受け渡しは大きなオブジェクトや変更可能なパラメータに適しており、ポインタを渡すのが最も高速です。戻り値の最適化の観点から、小さな値は直接返すことができ、大きなオブジェクトは参照またはポインターを返す必要があります。適切な戦略を選択すると、関数呼び出しのパフォーマンスが向上します。

JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 はじめに: 今日、天気予報の精度は日常生活と意思決定にとって非常に重要です。テクノロジーの発展に伴い、リアルタイムで気象データを取得することで、より正確で信頼性の高い天気予報を提供できるようになりました。この記事では、JavaScript と WebSocket テクノロジを使用して効率的なリアルタイム天気予報システムを構築する方法を学びます。この記事では、具体的なコード例を通じて実装プロセスを説明します。私たちは

C++ でのモジュール間での関数の呼び出し: 関数の宣言: ターゲット モジュールのヘッダー ファイルで呼び出される関数を宣言します。関数の実装: ソースファイルに関数を実装します。モジュールのリンク: リンカーを使用して、関数宣言と実装を含むモジュールをリンクします。関数の呼び出し:呼び出したいモジュールに対象モジュールのヘッダファイルを組み込み、関数を呼び出します。

JavaScript チュートリアル: HTTP ステータス コードを取得する方法、特定のコード例が必要です 序文: Web 開発では、サーバーとのデータ対話が頻繁に発生します。サーバーと通信するとき、多くの場合、返された HTTP ステータス コードを取得して操作が成功したかどうかを判断し、さまざまなステータス コードに基づいて対応する処理を実行する必要があります。この記事では、JavaScript を使用して HTTP ステータス コードを取得する方法を説明し、いくつかの実用的なコード例を示します。 XMLHttpRequestの使用

C++ 関数呼び出しリフレクション テクノロジにより、実行時に関数パラメータと戻り値の情報を動的に取得できます。 typeid(decltype(...)) および decltype(...) 式を使用して、パラメーターと戻り値の型情報を取得します。リフレクションを通じて、関数を動的に呼び出し、ランタイム入力に基づいて特定の関数を選択できるため、柔軟でスケーラブルなコードが可能になります。
