検索
ホームページウェブフロントエンドjsチュートリアルJavaScriptプログラミングにおけるこのキーワードの使用法を徹底分析_基礎知識

JavaScript ではこれは正確には何を意味しますか?多くの人は、これは現在のオブジェクトを指していると言うでしょう。これは正しいですか?ほとんどの場合、それが当てはまります。たとえば、Web ページでは次のような JavaScript をよく書きます:

<input type="submit" value="提交" onclick="this.value='正在提交数据'" />

これは明らかに現在のオブジェクト、つまり送信ボタンを指します。通常、これを使用するときの状況はこれに似ています。しかし、そうでない状況はあるのでしょうか?

この例を見てください:

var foo = function() {
  console.log(this);
}
foo();
new foo();

foo() と new foo() の実行結果を比較すると、前者では foo 自体を指しているのではなく、現在のページの window オブジェクトを指しているのに対し、後者は実際に foo を指していることがわかります。 。これはなぜでしょうか?

実際、これには JavaScript の重要な機能、いわゆる「クロージャ」が関係しています。クロージャの概念は複雑ではありませんが、1 つまたは 2 つの文で明確に説明できるほど単純でもありません。 JavaScript のこの最も重要な機能については、今後の記事で詳しく説明します。ここで、私が伝えたいのは、JavaScript のスコープはクロージャのために非常に重要になるということです。

いわゆるスコープとは、簡単に言えば、関数が作成される環境を指します。この変数の値が指定されていない場合、関数の現在のスコープになります。

前の例では、 foo() 関数はグローバル スコープ (ここでは window オブジェクト) 内にあるため、 this の値は現在の window オブジェクトになります。 new foo() の形式では、実際には foo() のコピーが作成され、このコピーに対して操作が実行されるため、これが foo() のコピーになります。

これは少し抽象的かもしれません。実際の例を見てみましょう:

<input type="button" id="aButton" value="demo" onclick="" />
<script type="text/javascript">
function demo() {
  this.value = Math.random();
}
</script>

demo() 関数を直接呼び出すと、プログラムはエラーを報告します。これは、demo 関数が window オブジェクトで定義されているため、demo の所有者 (スコープ) が wi​​ndow であり、demo の this も window であるためです。ウィンドウには value 属性がないため、エラーが報告されました。

2015119174624685.png (391×372)

コピーを作成してこの関数のコピーを HTML 要素に追加すると、その所有者がこの要素になり、これもこの要素を参照します:

document.getElementById("aButton").onclick = demo;

これは、aButton の onlick 属性を demo() のコピーに設定し、これも aButton を指します。

2015119174656357.png (391×373)

複数の異なる HTML 要素に対して関数の異なるコピーを作成することもできます。各コピーの所有者は対応する HTML 要素であり、それぞれの this も所有者を指すため、混乱は生じません。

2015119174716805.png (391×482)

ただし、要素の onlick イベントを次のように定義すると、

<input type="button" id="aButton" value="demo" onclick="demo()" />

このボタンをクリックすると、プログラムが再度エラーを報告することがわかります。これは再びウィンドウを示しています。

実際には、このメソッドはプログラムに関数を作成するのではなく、関数を参照するだけです。

違いを詳しく見てみましょう。

関数のコピーを作成するメソッドを使用します:

<input type="button" id="aButton" value="demo" />
<script type="text/javascript">
var button = document.getElementById("aButton");
function demo() {
  this.value = Math.random();
}
button.onclick= demo;
alert(button.onclick);
</script>

結果の出力は次のとおりです:

function demo() {
  this.value = Math.random();
}

関数参照の使用方法:

<input type="button" id="aButton" value="demo" onclick="demo()" />

結果の出力は次のとおりです:

function onclick() {
  demo();
}

こうすると違いがわかります。関数参照メソッドでは、onclick イベントは、demo() 関数を直接呼び出すだけであり、demo() 関数のスコープは依然として window オブジェクトであるため、これは引き続きウィンドウを指します。

2015119174740033.png (391×368)

これにより、別の疑問が生じます。関数のコピーは非常に簡単に使用できるのに、なぜ関数参照が必要なのでしょうか?答えはパフォーマンスです。関数のコピーが作成されるたびに、プログラムは関数のコピーに一定量のメモリを割り当てます。実際のアプリケーションでは、ほとんどの関数は必ずしも呼び出されるとは限らないため、メモリのこの部分は無駄になります。関数参照を使用すると、プログラムは関数自体にメモリのみを割り当てますが、参照ではポインターのみが割り当てられるため、はるかに効率的です。プログラマーの皆さん、節約が一番大事ですね

それでは、より良い解決策を見てみましょう:

<script type="text/javascript">
function demo(obj) {
  obj.value = Math.random();
}
</script>
<input type="button" value="demo" onclick="demo(this)" />
<input type="button" value="demo" onclick="demo(this)" />
<input type="button" value="demo" onclick="demo(this)" />

 

这样,效率和需求就都能兼顾了。

 
this的指向
JavaScript由于其在运行期进行绑定的特性,JavaScript 中的 this 可以是全局对象、当前对象或者任意对象,这完全取决于函数的调用方式。JavaScript 中函数的调用有以下几种方式:作为对象方法调用,作为函数调用,作为构造函数调用,和使用 apply 或 call 调用。常言道,字不如表,表不如图。为了让人更好的理解JavaScript this 到底指向什么?下面用一张图来进行解释:

2015119174758093.jpg (1251×421)

上图我称之为”JavaScript this决策树“(非严格模式下)。下面通过例子来说明这个图如何来帮助我们对this进行判断:

var point = { 
 x : 0, 
 y : 0, 
 moveTo : function(x, y) { 
   this.x = this.x + x; 
   this.y = this.y + y; 
   } 
 };
//决策树解释:point.moveTo(1,1)函数不是new进行调用,进入否决策,
//是用dot(.)进行调用,则指向.moveTo之前的调用对象,即point
point.moveTo(1,1); //this 绑定到当前对象,即point对象

point.moveTo()函数在 “JavaScript this决策树“中进行判定的过程是这样的:

1)point.moveTo函数调用是用new进行调用的么?这个明显不是,进入“否”分支,即函数是否用dot(.)进行调用?;

2)point.moveTo函数是用dot(.)进行调用的,即进入“是”分支,即这里的this指向point.moveTo中.之前的对象point;

图解point.moveTo函数的this指向什么的解析图如下图所示:

2015119175054859.jpg (1245×416)

再举例,看下面的代码:

function func(x) { 
 this.x = x; 
 } 
func(5); //this是全局对象window,x为全局变量
//决策树解析:func()函数是用new进行调用的么?为否,进入func()函数是用dot进行调用的么?为否,则 this指向全局对象window
x;//x => 5

func()函数在 “JavaScript this决策树“中进行判定的过程是这样的:

1)func(5)函数调用是用new进行调用的么?这个明显不是,进入“否”分支,即函数是否用dot(.)进行调用?;

2)func(5)函数不是用dot(.)进行调用的,即进入“否”分支,即这里的this指向全局变量window,那么this.x实际上就是window.x;

图解func函数的this指向什么的解析图如下图所示:

2015119175222664.jpg (1242×416)

针对作为函数直接调用的方式,下面看一个复杂的例子:

var point = { 
 x : 0, 
 y : 0, 
 moveTo : function(x, y) { 
   // 内部函数
   var moveX = function(x) { 
   this.x = x;//this 指向什么?window
  }; 
  // 内部函数
  var moveY = function(y) { 
  this.y = y;//this 指向什么?window
  }; 
  moveX(x); 
  moveY(y); 
  } 
 }; 
 point.moveTo(1,1); 
 point.x; //=>0 
 point.y; //=>0 
 x; //=>1 
 y; //=>1

point.moveTo(1,1)函数实际内部调用的是moveX()和moveY()函数, moveX()函数内部的this在 “JavaScript this决策树“中进行判定的过程是这样的:

1)moveX(1)函数调用是用new进行调用的么?这个明显不是,进入“否”分支,即函数是否用dot(.)进行调用?;

2)moveX(1)函数不是用dot(.)进行调用的,即进入“否”分支,即这里的this指向全局变量window,那么this.x实际上就是window.x;

下面看一下作为构造函数调用的例子:

function Point(x,y){ 
  this.x = x; // this &#63;
  this.y = y; // this &#63;
 }
var np=new Point(1,1);
np.x;//1
var p=Point(2,2);
p.x;//error, p是一个空对象undefined
window.x;//2

Point(1,1)函数在var np=new Point(1,1)中的this在 “JavaScript this决策树“中进行判定的过程是这样的:

1)var np=new Point(1,1)调用是用new进行调用的么?这个明显是,进入“是”分支,即this指向np;

2)那么this.x=1,即np.x=1;

Point(2,2)函数在var p= Point(2,2)中的this在 “JavaScript this决策树“中进行判定的过程是这样的:

1)var p= Point(2,2)调用是用new进行调用的么?这个明显不是,进入“否”分支,即函数是否用dot(.)进行调用?;

2)Point(2,2)函数不是用dot(.)进行调用的?判定为否,即进入“否”分支,即这里的this指向全局变量window,那么this.x实际上就是window.x;

3)this.x=2即window.x=2.

最后看一下函数用call 和apply进行调用的例子:

function Point(x, y){ 
  this.x = x; 
  this.y = y; 
  this.moveTo = function(x, y){ 
    this.x = x; 
    this.y = y; 
  } 
 } 

var p1 = new Point(0, 0); 
var p2 = {x: 0, y: 0}; 
p1.moveTo.apply(p2, [10, 10]);//apply实际上为p2.moveTo(10,10)
p2.x//10

「JavaScript this 決定木」の p1.moveTo.apply(p2,[10,10]) 関数の処理は次のとおりです。

apply と call の 2 つのメソッドは、関数実行のコンテキスト、つまりこれにバインドされているオブジェクトを切り替えることができることが非常に強力であることがわかります。 p1.moveTo.apply(p2,[10,10]) は実際には p2.moveTo(10,10) です。 p2.moveTo(10,10) は次のように解釈できます:

1) p2.moveTo(10,10) 関数は new を使用して呼び出されていますか?これは明らかに当てはまりません。「いいえ」分岐に進みます。つまり、関数は dot(.) で呼び出されますか? ;

2) p2.moveTo(10,10) 関数は dot(.) で呼び出されます。つまり、「yes」分岐に入ります。つまり、ここでは、これは p2.moveTo( 10,10) なので、p2.x=10;

JavaScript 関数の実行環境のプロセスについては、IBM Developerworks ドキュメント ライブラリに非常に優れた説明があります。その抜粋は次のとおりです。

「JavaScript の関数は、通常の関数またはオブジェクトのメソッドとして実行できます。これが、関数が実行されるときに実行環境 (ExecutionContext) が作成される主な理由です。関数の動作は、この実行環境で発生します。JavaScript は、関数呼び出し時に渡されるパラメーターを含む引数変数を最初に作成し、それを最初に初期化します。関数のパラメータ リストの値は、引数変数の対応する値です。関数に内部関数が含まれている場合、仮パラメータは未定義に初期化されます。この関数で定義されたローカル変数については、この時点で未定義に初期化され、実行環境 (ExecutionContext) の後に関数が実行されるまでその代入操作は実行されないことに注意してください。これは、JavaScript における変数の役割を理解する上で非常に重要です。スペースの観点から、このトピックについては説明しません。最後に、この変数に値を割り当てます。上記では、関数呼び出しメソッド (この時点まで) が正常に作成され、関数が 1 行ずつ実行を開始し、必要な変数が読み取られることに応じて、このグローバル オブジェクト、現在のオブジェクトなどに割り当てられます。先ほど構築した実行環境(ExecutionContext)”
から。 この段落を理解することは、JavaScript 関数を理解する上で大いに役立ちます。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
JavaScriptエンジンの理解:実装の詳細JavaScriptエンジンの理解:実装の詳細Apr 17, 2025 am 12:05 AM

JavaScriptエンジンが内部的にどのように機能するかを理解することは、開発者にとってより効率的なコードの作成とパフォーマンスのボトルネックと最適化戦略の理解に役立つためです。 1)エンジンのワークフローには、3つの段階が含まれます。解析、コンパイル、実行。 2)実行プロセス中、エンジンはインラインキャッシュや非表示クラスなどの動的最適化を実行します。 3)ベストプラクティスには、グローバル変数の避け、ループの最適化、constとletsの使用、閉鎖の過度の使用の回避が含まれます。

Python vs. JavaScript:学習曲線と使いやすさPython vs. JavaScript:学習曲線と使いやすさApr 16, 2025 am 12:12 AM

Pythonは、スムーズな学習曲線と簡潔な構文を備えた初心者により適しています。 JavaScriptは、急な学習曲線と柔軟な構文を備えたフロントエンド開発に適しています。 1。Python構文は直感的で、データサイエンスやバックエンド開発に適しています。 2。JavaScriptは柔軟で、フロントエンドおよびサーバー側のプログラミングで広く使用されています。

Python vs. JavaScript:コミュニティ、ライブラリ、リソースPython vs. JavaScript:コミュニティ、ライブラリ、リソースApr 15, 2025 am 12:16 AM

PythonとJavaScriptには、コミュニティ、ライブラリ、リソースの観点から、独自の利点と短所があります。 1)Pythonコミュニティはフレンドリーで初心者に適していますが、フロントエンドの開発リソースはJavaScriptほど豊富ではありません。 2)Pythonはデータサイエンスおよび機械学習ライブラリで強力ですが、JavaScriptはフロントエンド開発ライブラリとフレームワークで優れています。 3)どちらも豊富な学習リソースを持っていますが、Pythonは公式文書から始めるのに適していますが、JavaScriptはMDNWebDocsにより優れています。選択は、プロジェクトのニーズと個人的な関心に基づいている必要があります。

C/CからJavaScriptへ:すべてがどのように機能するかC/CからJavaScriptへ:すべてがどのように機能するかApr 14, 2025 am 12:05 AM

C/CからJavaScriptへのシフトには、動的なタイピング、ゴミ収集、非同期プログラミングへの適応が必要です。 1)C/Cは、手動メモリ管理を必要とする静的に型付けられた言語であり、JavaScriptは動的に型付けされ、ごみ収集が自動的に処理されます。 2)C/Cはマシンコードにコンパイルする必要がありますが、JavaScriptは解釈言語です。 3)JavaScriptは、閉鎖、プロトタイプチェーン、約束などの概念を導入します。これにより、柔軟性と非同期プログラミング機能が向上します。

JavaScriptエンジン:実装の比較JavaScriptエンジン:実装の比較Apr 13, 2025 am 12:05 AM

さまざまなJavaScriptエンジンは、各エンジンの実装原則と最適化戦略が異なるため、JavaScriptコードを解析および実行するときに異なる効果をもたらします。 1。語彙分析:ソースコードを語彙ユニットに変換します。 2。文法分析:抽象的な構文ツリーを生成します。 3。最適化とコンパイル:JITコンパイラを介してマシンコードを生成します。 4。実行:マシンコードを実行します。 V8エンジンはインスタントコンピレーションと非表示クラスを通じて最適化され、Spidermonkeyはタイプ推論システムを使用して、同じコードで異なるパフォーマンスパフォーマンスをもたらします。

ブラウザを超えて:現実世界のJavaScriptブラウザを超えて:現実世界のJavaScriptApr 12, 2025 am 12:06 AM

現実世界におけるJavaScriptのアプリケーションには、サーバー側のプログラミング、モバイルアプリケーション開発、モノのインターネット制御が含まれます。 2。モバイルアプリケーションの開発は、ReactNativeを通じて実行され、クロスプラットフォームの展開をサポートします。 3.ハードウェアの相互作用に適したJohnny-Fiveライブラリを介したIoTデバイス制御に使用されます。

next.jsを使用してマルチテナントSaaSアプリケーションを構築する(バックエンド統合)next.jsを使用してマルチテナントSaaSアプリケーションを構築する(バックエンド統合)Apr 11, 2025 am 08:23 AM

私はあなたの日常的な技術ツールを使用して機能的なマルチテナントSaaSアプリケーション(EDTECHアプリ)を作成しましたが、あなたは同じことをすることができます。 まず、マルチテナントSaaSアプリケーションとは何ですか? マルチテナントSaaSアプリケーションを使用すると、Singの複数の顧客にサービスを提供できます

next.jsを使用してマルチテナントSaaSアプリケーションを構築する方法(フロントエンド統合)next.jsを使用してマルチテナントSaaSアプリケーションを構築する方法(フロントエンド統合)Apr 11, 2025 am 08:22 AM

この記事では、許可によって保護されたバックエンドとのフロントエンド統合を示し、next.jsを使用して機能的なedtech SaaSアプリケーションを構築します。 FrontEndはユーザーのアクセス許可を取得してUIの可視性を制御し、APIリクエストがロールベースに付着することを保証します

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

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

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SecLists

SecLists

SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

DVWA

DVWA

Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強力な PHP 統合開発環境