ホームページ ウェブフロントエンド jsチュートリアル js_javascript スキルの this キーワードを理解する

js_javascript スキルの this キーワードを理解する

May 16, 2016 pm 03:44 PM

このキーワードは c と java の両方で提供されています。最初に学習し始めると難しいですが、一度理解すると、このキーワードを理解するという記事で js で詳しく説明します。 。

これに関しては、多くのフロントエンド面接で必須の質問ですが、時々インターネットでこれらの質問を見て、自分で試してみました。実際の開発でも、この問題に遭遇します (ただし、一部のクラス ライブラリがこの問題に対処するのに役立ちます)。たとえば、ノックアウトなどのフレームワークを使用する場合、なぜこれを直接使用しないのか理解できないことがあります。ですが、パラメータが渡されるのでこれを使用します。

次に、私の理解と今後の参考のためのメモとしてお話します。間違っているところがあれば、指摘、批判してください。

1. C# とは異なり、これは現在のオブジェクトを指す必要があります。

js の this 点は不確実ですが、動的に変更できることを意味します。 call/apply は、これが指すポイントを変更するために使用される関数です。この設計により、コードがより柔軟で再利用可能になります。

2. これは通常、関数の所有者を指します。

これはとても重要です!これはとても重要です!これはとても重要です!

これは面接でよくある質問でもあり、コードは次のとおりです:

<script type="text/javascript">
  var number = 1;
  var obj = {
     number: 2,
    showNumber: function(){
      this.number = 3;
      (function(){          
        console.log(this.number);
      })();
      console.log(this.number);
    }
  };
  obj.showNumber();
</script>
ログイン後にコピー

showNumber メソッドの所有者は obj なので、this.number=3; これは obj の属性番号を指します。

同様に、2 番目の console.log にも属性番号が出力されます。

2 番目の点で、一般的にこれが関数の所有者を指すとしているのはなぜですか。特別な事情があるからです。関数の自己実行は特殊なケースであり、関数の自己実行では、これはウィンドウを指します。したがって、最初の console.log にはウィンドウの属性番号が出力されます。

そこで、少し追加する必要があります:

3. 関数の自己実行では、これはウィンドウ オブジェクトを指します。

補足ですが、これに関して、もう 1 つややこしいのが、DOM イベントには通常、次の 3 つの状況があるということです。

以下のように:

1. label 属性を使用してイベントを登録します。このとき、これは window オブジェクトを指します。

<input id="test" type="button" value="按钮" onClick="test()"/>
  function test(){alert(this)}
ログイン後にコピー

2. 1 の場合、これを入力に指定するには、これをパラメーターとして渡すことができます。

3. addEventListener などを使用して登録します。このとき、これも入力を指します。

document.getElementById("test").addEventListener("click",test);
ログイン後にコピー

オブジェクト指向プログラミング言語では、this キーワードがよく知られています。たとえば、C、C#、Java にはすべてこのキーワードがありますが、学習の初めは難しくても、一度理解すると非常に便利で有意義です。 JavaScript にもこのキーワードはありますが、古典的な OO 言語よりも使用するのがはるかに「混乱」します。

JavaScript でこれを使用するさまざまな方法の何が混乱しているのかを見てみましょう。

1. このキーワードを HTML 要素のイベント属性でインラインで使用します:

// 可以在里面使用this  
">division element 
 // 可以在里面使用this
 ">division element 
ログイン後にコピー

ここで使用する最も一般的なメソッドは、javascirpt: EventHandler(this) の形式です。ただし、必要に応じて、実際にはここに任意の正当な JavaScript ステートメントを記述することができます (ただし、これは内部クラスになります)。ここでの原則は、スクリプト エンジンが div インスタンス オブジェクトの匿名メンバー メソッドを生成し、onclick がこのメソッドを指すということです。

2. DOM メソッドを使用して、イベント処理関数でこのキーワードを使用します:

division element

 var div = document.getElementById('elmtDiv');  
 div.attachEvent('onclick', EventHandler);  
 
 function EventHandler()  
 {  
 // 在此使用this  
 }  
  
// --> 
 
division element

 var div = document.getElementById('elmtDiv');
 div.attachEvent('onclick', EventHandler);

 function EventHandler()
 {
 // 在此使用this
 }
 
// --> 
ログイン後にコピー

このとき、EventHandler() メソッドの this キーワードは、オブジェクトが IE ウィンドウ オブジェクトであることを示します。これは、EventHandler が単なる通常の関数であるため、attachEvent の後のスクリプト エンジンの呼び出しは div オブジェクト自体とは何の関係もありません。同時に、EventHandler の caller 属性 (null に等しい) を確認できます。このメソッドで div オブジェクト参照を取得したい場合は、this.event.srcElement を使用する必要があります。

3. DHTML を使用して、イベント処理関数でこのキーワードを使用します:

division element
  
lt;mce:script language="javascript">
var div = document.getElementById('elmtDiv');  
div.onclick = function()  
{  
 // 在此使用this  
};  
 
/ --> 
 
division element

 var div = document.getElementById('elmtDiv');
 div.onclick = function()
 {
 // 在此使用this
 };
 
// --> 
ログイン後にコピー

ここで this キーワードで示される内容は、div 要素のオブジェクトのインスタンスです。スクリプト内で DHTML を使用して、div.onclick に直接 EventHandler メソッドを割り当てることは、div オブジェクトのインスタンスにメンバー メソッドを追加することと同じです。このメソッドと最初のメソッドの違いは、最初のメソッドは HTML メソッドを使用するのに対し、後者のスクリプト解析エンジンは匿名メソッドを生成しなくなることです。

4. クラス定義で次のキーワードを使用します:

function JSClass()  
{  
var myName = 'jsclass';  
this.m_Name = 'JSClass';  
}  
 
JSClass.prototype.ToString = function()  
{  
alert(myName + ', ' + this.m_Name);  
};  
 
var jc = new JSClass();  
jc.ToString(); 
 function JSClass()
 {
 var myName = 'jsclass';
 this.m_Name = 'JSClass';
 }

 JSClass.prototype.ToString = function()
 {
 alert(myName + ', ' + this.m_Name);
 };

 var jc = new JSClass();
 jc.ToString(); 
ログイン後にコピー

这是JavaScript模拟类定义中对this的使用,这个和其它的OO语言中的情况非常的相识。但是这里要求成员属性和方法必须使用this关键字来引用,运行上面的程序会被告知myName未定义。

5、为脚本引擎内部对象添加原形方法中的this关键字:

function.prototype.GetName = function()  
{  
var fnName = this.toString();  
fnName = fnName.substr(0, fnName.indexOf('('));  
fnName = fnName.replace(/^function/, '');  
return fnName.replace(/(^\s+)|(\s+$)/g, '');  
}  
function foo(){}  
alert(foo.GetName());  
 function.prototype.GetName = function()
 {
 var fnName = this.toString(); 
 fnName = fnName.substr(0, fnName.indexOf('(')); 
 fnName = fnName.replace(/^function/, ''); 
 return fnName.replace(/(^\s+)|(\s+$)/g, '');
 }
 function foo(){}
 alert(foo.GetName()); 
ログイン後にコピー

这里的this指代的是被添加原形的类的实例,和4中类定义有些相似,没有什么太特别的地方。

6、结合2&4,说一个比较迷惑的this关键字使用:

view plaincopy to clipboardprint&#63;
function JSClass()  
{  
this.m_Text = 'division element';  
this.m_Element = document.createElement('DIV');  
this.m_Element.innerHTML = this.m_Text;  
  
this.m_Element.attachEvent('onclick', this.ToString);  
}  
  
JSClass.prototype.Render = function()  
{  
document.body.appendChild(this.m_Element);  
}   
 
JSClass.prototype.ToString = function()  
{  
alert(this.m_Text);  
};  
 
var jc = new JSClass();  
jc.Render();  
jc.ToString(); 
 function JSClass()
 {
 this.m_Text = 'division element';
 this.m_Element = document.createElement('DIV');
 this.m_Element.innerHTML = this.m_Text;
  
 this.m_Element.attachEvent('onclick', this.ToString);
 }
  
 JSClass.prototype.Render = function()
 {
 document.body.appendChild(this.m_Element);
 } 

 JSClass.prototype.ToString = function()
 {
 alert(this.m_Text);
 };

 var jc = new JSClass();
 jc.Render(); 
 jc.ToString(); 
ログイン後にコピー

我就说说结果,页面运行后会显示:"division element",确定后点击文字"division element",将会显示:"undefined"。

7、CSS的expression表达式中使用this关键字:

height: expression(this.parentElement.height);">  
 division element  
  
 height: expression(this.parentElement.height);">
 division element
ログイン後にコピー

这里的this看作和1中的一样就可以了,它也是指代div元素对象实例本身。

8、函数中的内部函数中使用this关键字:

view plaincopy to clipboardprint&#63;
function OuterFoo()  
{  
this.Name = 'Outer Name';  
 
function InnerFoo()  
{  
var Name = 'Inner Name';  
alert(Name + ', ' + this.Name);  
}  
return InnerFoo;  
}  
OuterFoo()(); 
 function OuterFoo()
 {
 this.Name = 'Outer Name';
 
 function InnerFoo()
 {
 var Name = 'Inner Name'; 
 alert(Name + ', ' + this.Name);
 }
 return InnerFoo;
 }
 OuterFoo()(); 
ログイン後にコピー

运行结果显示是:"Inner Name, Outer Name"。按我们在2中的讲解,这里的结果如果是"Inner Name, undefined"似乎更合理些吧?但是正确的结果确实是前者,这是由于JavaScript变量作用域的问题决定的,详细了解推荐参看"原来JScript中的关键字'var'还是有文章的"一文及回复。

归纳起来,JavaScript中的this用法有以下3种(详细用法参原文):

1.在HTML元素事件属性 或 CSS的expression表达式 中inline方式使用this关键字——对应原文的1、7

2.在事件处理函数中使用this关键字——对应原文的2、3

其中可分为两种方式

(1)DOM方式——此种方式的结果是this指向窗口(window)对象

(2)DHTML方式——此种方式的结果是this指向div元素对象实例

3.在类定义中使用this关键字并在其 内部函数 或 成员函数(主要是prototype产生)中使用——对应原文的4、5、8

需要说明的是,在函数也是个对象,因此需要区分 变量定义 和 成员变量定义,如下:

view plaincopy to clipboardprint&#63;

var variableName;    //变量定义  
//作用域:函数定义范围内  
//使用方法:直接使用variableName  
this.varName;      //成员变量定义  
//作用域:函数对象定义范围内及其成员函数中  
//使用方法:this.varName 
var variableName;    //变量定义
//作用域:函数定义范围内
//使用方法:直接使用variableName
this.varName;      //成员变量定义
//作用域:函数对象定义范围内及其成员函数中
//使用方法:this.varName
ログイン後にコピー

以上归纳出的三类this的使用方法中,第一种比较容易理解,这里对原文中第6点提到的程序进行了测试和改进如下,以说明上述后两种使用方法:

view plaincopy to clipboardprint&#63;

    function JSClass()  
    {  
      var varText = "func variable!";                 //函数中的普通变量  
      this.m_Text = 'func member!';                    //函数类的成员变量  
      this.m_Element = document.createElement('DIV');   //成员变量,创建一个div对象  
      this.m_Element.innerHTML = varText;             //使用函数的普通变量  
      this.m_Element.attachEvent('onclick', this.ToString);  //给这个对象的事件连上处理函数  
      this.newElement = document.createElement('DIV');  
      this.newElement.innerHTML = "new element";   
      this.newElement.m_Text = "new element text!";      //给创建的对象建个成员  
      this.newElement.onclick = function()  
      {  
        alert(this.m_Text);                       //指向div对象的成员  
      };  
    }  
   
    JSClass.prototype.Render = function()  
    {  
      document.body.appendChild(this.m_Element);       //把div对象挂在窗口上  
      document.body.appendChild(this.newElement);  
    }    
 
    JSClass.prototype.ToString = function()  
    {  
      alert(this.m_Text);                         //指向窗口(window)对象  
    };  
 
    function initialize(){  
      var jc = new JSClass();  
      jc.Render();  
      jc.ToString();                             //里面的this指向JSClass类的实例,里面有m_Text成员  
    }  
    
// -->  

    initialize();  
    
// -->  
  
 function JSClass()
  {
   var varText = "func variable!";     //函数中的普通变量
    this.m_Text = 'func member!';     //函数类的成员变量
    this.m_Element = document.createElement('DIV'); //成员变量,创建一个div对象
    this.m_Element.innerHTML = varText;    //使用函数的普通变量
    this.m_Element.attachEvent('onclick', this.ToString); //给这个对象的事件连上处理函数
    this.newElement = document.createElement('DIV');
    this.newElement.innerHTML = "new element"; 
    this.newElement.m_Text = "new element text!";  //给创建的对象建个成员
    this.newElement.onclick = function()
   {
     alert(this.m_Text);      //指向div对象的成员
   };
  }
  
  JSClass.prototype.Render = function()
  {
    document.body.appendChild(this.m_Element);  //把div对象挂在窗口上
    document.body.appendChild(this.newElement);
  }   

  JSClass.prototype.ToString = function()
  {
    alert(this.m_Text);       //指向窗口(window)对象
  };

 function initialize(){
   var jc = new JSClass();
   jc.Render(); 
   jc.ToString();        //里面的this指向JSClass类的实例,里面有m_Text成员
  }
  
// -->

   initialize();
  
// -->
ログイン後にコピー

上面的代码执行结果是:

页面加载时,弹出对话框,输出func member!

页面上显示

 func variable!
 new element
ログイン後にコピー

单击func variable时,弹出对话框,显示undefined

  ——因为这时toString函数里的this指针指向window

单击new element时,弹出对话框显示new element text!

  ——因为这时toString函数里的this指针指向div元素,而该元素已经定义了m_Text成员(this.newElement.m_Text = "new element text!")

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホット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

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

SublimeText3 中国語版

SublimeText3 中国語版

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

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

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

独自のJavaScriptライブラリを作成および公開するにはどうすればよいですか? 独自のJavaScriptライブラリを作成および公開するにはどうすればよいですか? Mar 18, 2025 pm 03:12 PM

記事では、JavaScriptライブラリの作成、公開、および維持について説明し、計画、開発、テスト、ドキュメント、およびプロモーション戦略に焦点を当てています。

ブラウザでのパフォーマンスのためにJavaScriptコードを最適化するにはどうすればよいですか? ブラウザでのパフォーマンスのためにJavaScriptコードを最適化するにはどうすればよいですか? Mar 18, 2025 pm 03:14 PM

この記事では、ブラウザでJavaScriptのパフォーマンスを最適化するための戦略について説明し、実行時間の短縮、ページの負荷速度への影響を最小限に抑えることに焦点を当てています。

フロントエンドのサーマルペーパーレシートのために文字化けしたコード印刷に遭遇した場合はどうすればよいですか? フロントエンドのサーマルペーパーレシートのために文字化けしたコード印刷に遭遇した場合はどうすればよいですか? Apr 04, 2025 pm 02:42 PM

フロントエンドのサーマルペーパーチケット印刷のためのよくある質問とソリューションフロントエンド開発におけるチケット印刷は、一般的な要件です。しかし、多くの開発者が実装しています...

ブラウザ開発者ツールを使用してJavaScriptコードを効果的にデバッグするにはどうすればよいですか? ブラウザ開発者ツールを使用してJavaScriptコードを効果的にデバッグするにはどうすればよいですか? Mar 18, 2025 pm 03:16 PM

この記事では、ブラウザ開発者ツールを使用した効果的なJavaScriptデバッグについて説明し、ブレークポイントの設定、コンソールの使用、パフォーマンスの分析に焦点を当てています。

誰がより多くのPythonまたはJavaScriptを支払われますか? 誰がより多くのPythonまたはJavaScriptを支払われますか? Apr 04, 2025 am 12:09 AM

スキルや業界のニーズに応じて、PythonおよびJavaScript開発者には絶対的な給与はありません。 1. Pythonは、データサイエンスと機械学習でさらに支払われる場合があります。 2。JavaScriptは、フロントエンドとフルスタックの開発に大きな需要があり、その給与もかなりです。 3。影響要因には、経験、地理的位置、会社の規模、特定のスキルが含まれます。

ソースマップを使用して、マイナイドJavaScriptコードをデバッグするにはどうすればよいですか? ソースマップを使用して、マイナイドJavaScriptコードをデバッグするにはどうすればよいですか? Mar 18, 2025 pm 03:17 PM

この記事では、ソースマップを使用して、元のコードにマッピングすることにより、Minified JavaScriptをデバッグする方法について説明します。ソースマップの有効化、ブレークポイントの設定、Chrome DevtoolsやWebpackなどのツールの使用について説明します。

Console.log出力の違い結果:なぜ2つの呼び出しが異なるのですか? Console.log出力の違い結果:なぜ2つの呼び出しが異なるのですか? Apr 04, 2025 pm 05:12 PM

Console.log出力の違いの根本原因に関する詳細な議論。この記事では、Console.log関数の出力結果の違いをコードの一部で分析し、その背後にある理由を説明します。 �...

初心者向けのタイプスクリプト、パート2:基本データ型 初心者向けのタイプスクリプト、パート2:基本データ型 Mar 19, 2025 am 09:10 AM

エントリーレベルのタイプスクリプトチュートリアルをマスターしたら、TypeScriptをサポートするIDEで独自のコードを作成し、JavaScriptにコンパイルできるはずです。このチュートリアルは、TypeScriptのさまざまなデータ型に飛び込みます。 JavaScriptには、NULL、未定義、ブール値、数字、文字列、シンボル(ES6によって導入)とオブジェクトの7つのデータ型があります。 TypeScriptはこれに基づいてより多くのタイプを定義し、このチュートリアルではすべてを詳細に説明します。 ヌルデータ型 JavaScriptのように、Typescriptのnull

See all articles