ホームページ ウェブフロントエンド jsチュートリアル JavaScript のこのポインターについての深い理解

JavaScript のこのポインターについての深い理解

Mar 17, 2018 pm 04:21 PM
javascript js this

この記事では主に、JavaScript の this ポインターについて詳しく説明します。Java を作成する際、これが誤って使用されると、idea は直接エラーを報告します。

たとえば...



オブジェクト指向プログラミングには 2 つの重要な概念があります: 1 つはクラスで、もう 1 つはインスタンス化されたオブジェクトです クラスは抽象概念です。メタファーの観点から言えば、クラスは型のようなものであり、インスタンス化されたオブジェクトは、その型を通して製造された製品です。ただし、クラスとインスタンス化されたオブジェクトの間には密接な関係があります。金型と金型で作られた製品の関係と同様に、クラスの機能はインスタンス化されたオブジェクトを置き換えることはできません。その用途は異なります。

上記のコードから、this ポインタは Java 言語のインスタンス化されたオブジェクトでのみ使用できることがわかり、このポインタはインスタンス化されたオブジェクトと等しく、この後にドット演算子が追加されます。物とは、名前、仕事、手、足など、これが所有する物です。

実際 JavaScript の this ポインターの論理概念もインスタンス化されたオブジェクトです。ただし、JavaScript の this ポインターは Java の this ポインターよりも理解するのがはるかに困難です。結局のところ、私は個人的に次の 3 つの基本的な理由があると考えています:

理由 1: JavaScript は関数型プログラミング言語です。奇妙なことに、この関数型プログラミング言語がオブジェクト指向言語でもあることを示すポインターもあります。具体的には、JavaScriptでは高階関数をオブジェクトとして渡すことができると同時に、このコンストラクターもJavaScriptで使用することができます。インスタンス化されたオブジェクトを作成すると、メソッドの実行時に this ポインターが生成され、方向は常に変化するため、制御が困難になります。

理由 2: JavaScript のグローバル スコープは this ポインターに大きな影響を与えます。上記の Java の例から、this ポインターは new 演算子を使用した後にのみ有効になることがわかりますが、JavaScript の this はそれです。現時点では、新しい操作が実行されない場合でも有効になります。多くの場合、これはグローバル オブジェクト ウィンドウを指します。

理由 3: JavaScript の call 演算子と apply 演算子は this ポインタを自由に変更できます。これは非常に柔軟に見えますが、この不合理なアプローチはこのポインタの本来の理解の意味を破壊し、また、作成時にこれを理解することを困難にします。



の本当のポイントは、このポインターを使用する従来の方法に違反しているためです。実際の開発では、これら 3 つの理由はすべて異なります。それらは絡み合う傾向があり、これはすべて雲の中です...


入門書: Web 開発者のための専門的な Javascript、- 上級バージョンは次のとおりです:

これは常にポイントしますto このメソッドが呼び出されるオブジェクトです。



var name="zhoulujun";

function Say(){

console.log(this.name)

}

say(); //zhoulujun



このポインタ (ウィンドウ オブジェクトを指す) は、次の場合でも直接使用できます 。三重等号が使用されている場合、それらは等しいです。グローバル スコープは、JavaScript 言語の特性の理解を妨げることがよくあります。この干渉の本質は次のとおりです。

JavaScript 言語では、グローバル スコープはウィンドウではなくオブジェクトとして理解される

。つまり、ウィンドウはインスタンス化されたオブジェクトです。プログラマーが制御できないため、ページ全体の要素は JavaScript エンジンによって完了します。プログラミング言語を通じてインスタンス化プロセスを操作するため、開発中にこのポインターを構築する感覚がなくなり、このポインターがコード内でウィンドウを指す状況を理解するのが妨げられることがよくあります。

ここでは、これは window オブジェクトを指しているので、this.name->zhoulujun!



say 関数が実行されると、JavaScript は Execute コンテキスト (実行コンテキスト) を作成します。実行コンテキストには、say 関数の実行時に必要なすべての情報が含まれます。実行コンテキストには独自のスコープ チェーンもあります。関数が実行されると、JavaScript エンジンはまず、say 関数を使用してスコープ チェーンから実行コンテキストのスコープ チェーンを初期化します。

ここで大まかに覚えておいてください:

var myObj={
name:"zhoulujun",
fn:function(){
console.log(this.name)
}
};
myObj.fn();
ログイン後にコピー


这里的this指向obj,因为fn()运行在obj里面……

然后再来看……

var name="zhoulujun";
function say(){
console.log(this.name)
console.log(this)
}
say();
function say2(){
var site="zhoulujun.cn";
console.log(this.site);
}
say2();
ログイン後にコピー


myObj2={
site:"zhoulujun.cn",
fn:function(){
console.log(this.site)
}
}
ログイン後にコピー



这里的this指向的是对象myObj2,因为你调用这个fn是通过myObj2.fn()执行的,那自然指向就是对象myObj2,这里再次强调一点,this的指向在函数创建的时候是决定不了的,在调用的时候才能决定,谁调用的就指向谁,一定要搞清楚这个

然后,我们更深入(受不了 …………

myObj3={
site:"zhoulujun.cn",
andy:{
site:"www.zhoulujun.cn",
fn:function(){
console.log(this.site)
}
}
};
myObj3.andy.fn();
ログイン後にコピー



这里同样也是对象Object点出来的,但是同样this并没有执行它,那你肯定会说我一开始说的那些不就都是错误的吗?其实也不是,只是一开始说的不准确,接下来我将补充一句话,我相信你就可以彻底的理解this的指向的问题。

如果,你实在理解不了,就这么样背下来吧!

情况1:如果一个函数中有this,但是它没有被上一级的对象所调用,那么this指向的就是window,这里需要说明的是在js的严格版中this指向的不是window,但是我们这里不探讨严格版的问题,你想了解可以自行上网查找。

情况2:如果一个函数中有this,这个函数有被上一级的对象所调用,那么this指向的就是上一级的对象。

情况3:如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象,如果不相信,那么接下来我们继续看几个例子。

这样既对了吗??深入点(就受不了了……讨厌……

myObj3={
site:"zhoulujun.cn",
andy:{
site:"www.zhoulujun.cn",
fn:function(){
console.log(this)
console.log(this.site)
}
}
};
//    myObj3.andy.fn();
var fn=myObj3.andy.fn;
fn();
ログイン後にコピー



其实,这里的 fn等价于

fn:function(age){

console.log(this.name+age);

}

下面我们来聊聊函数的定义方式:声明函数和函数表达式

我们最上面第一个案例定义函数的方式在javascript语言称作声明函数,第二种定义函数的方式叫做函数表达式,这两种方式我们通常认为是等价的,但是它们其实是有区别的,而这个区别常常会让我们混淆this指针的使用,我们再看看下面的代码:



say は実行できるのに、say3 は実行できないのはなぜですか?その理由は、



say3の出力結果が未定義である理由は、前回の記事で述べました未定義というのは、メモリのスタック領域に既に変数名が存在するという意味ですが、スタック領域に変数値がありません。同時に、ヒープ領域にも特定のオブジェクトがありません。これは、JavaScript エンジンがプリロード中に変数定義をスキャンすることが原因です。ただし、ftn01 の出力結果は非常に驚くべきものです。完成した関数定義が出力され、コードが順番に実行されない、これは 1 つの問題しか説明できません:

JavaScript 言語では、関数は関数を宣言することによって定義され、JavaScript エンジンは前処理中に関数の定義と割り当て操作を完了します。ここで、JavaScript における前処理の特徴を追加します。前処理は実行環境に関係します。実行環境には、グローバル実行環境とローカル実行環境の 2 つのカテゴリがあると述べました。実行環境はコンテキスト変数を通じて反映されます。実際、このプロセスは関数が実行される前に完了します。つまり、前処理と実行環境の構築の主な目的は、変数の定義を明確にすることです。ただし、グローバル スコープの構築中またはグローバル変数の前処理中の関数の宣言では、変数の定義と代入の操作が同時に完了するため、上記のコードの結果がわかります。 。宣言された関数はグローバル スコープの構築中に完成するため、宣言された関数はすべて window オブジェクトの属性になります。これは、関数をどこで宣言しても、宣言された関数が最終的に window オブジェクトに属する理由を説明します。

ここで見ることをお勧めします - Java クラスの実行順序:

http://www.zhoulujun.cn/zhoulujun/html/java/javaBase/7704.html



其实在javascript语言里任何匿名函数都是属于window对象,它们也都是在全局作用域构造时候完成定义和赋值,但是匿名函数是没有名字的函数变量,但是在定义匿名函数时候它会返回自己的内存地址,如果此时有个变量接收了这个内存地址,那么匿名函数就能在程序里被使用了,因为匿名函数也是在全局执行环境构造时候定义和赋值,所以匿名函数的this指向也是window对象,所以上面代码执行时候fn的this都是指向window,因为javascript变量名称不管在那个作用域有效,堆区的存储的函数都是在全局执行环境时候就被固定下来了,变量的名字只是一个指代而已。

类似的情况(面试题喜欢这么考!)……比如:



this都是指向实例化对象,前面讲到那么多情况this都指向window,就是因为这些时候只做了一次实例化操作,而这个实例化都是在实例化window对象,所以this都是指向window。我们要把this从window变成别的对象,就得要让function被实例化,那如何让javascript的function实例化呢?答案就是使用new操作符。

再来看 构造函数:

function  User(){
this.name="zhoulujun";
console.log(this);
}
var andy=new User();
console.log(andy.name)
ログイン後にコピー



why andy 的name 是 zhoulujun,那是:因为:

new关键字可以改变this的指向,将这个this指向对象andy,

那andy什么时候又成了思密达,oh,no,is Object?

new キーワードを使用すると、オブジェクト インスタンスが作成されるためです (重要なことを 3 回静かに読んでください)

変数 andy を使用して、User ユーザー インスタンスを作成します (User のコピーをオブジェクト andy にコピーするのと同じです)。これは作成されただけで実行されていません。この関数 User を呼び出すオブジェクトはオブジェクト andy なので、オブジェクト User に名前があるのはなぜでしょうか。オブジェクト andy に対して new キーワードを使用することは、コピーを作成することと同じです。

java プログラマ: Class user=new User(); は見覚えのあるものですね...



function

が関数である場合、それは関数でもあり、オブジェクトでもあります。 javascriptのコンストラクターは、クラスとコンストラクターを1つに結合したものだとよく思いますもちろん、javascriptの言語仕様にはクラスの概念はありませんが、私の理解では次のようになります。コンストラクターと通常の関数として使用される関数の違いは、こうすることで理解しやすくなります 以下に、「JavaScript 高度なプログラミング」の新しい演算子の説明を掲載します。 新しい演算子は、コンストラクターに次の変更を加えます。

1. 新しいオブジェクトを作成します。コンストラクターのスコープが新しいオブジェクトに割り当てられます (つまり、これは新しいオブジェクトを指します)

3. コンストラクターでコードを実行します (この新しいオブジェクトに属性を追加します)。

4. 返回新对象

……

妈的:读的那么拗口,不明觉厉…………看图……还不

不明白……

var myObj5={
name:"andy"
};
var myObj6=new Object();
myObj6.name="andy";
function  say5(name){
console.log(name)
}
var say6=new Function("name","console.log(name)");
console.log(myObj5)
console.log(myObj6)
say5("andy");
say6("andy");
ログイン後にコピー



还不明白,就请奶奶买块豆腐,撞死算了……

第四点也要着重讲下,记住构造函数被new操作,要让new正常作用最好不能在构造函数里写return,没有return的构造函数都是按上面四点执行,有了return情况就复杂了

return这王八蛋……



那么我这样呢……



does it have to be like this?Tell me why(why),is there something I have missed?

Tell me why(why),cos I don't understand…………



那是因为……because of u?no return……



所以:如果返回的是基本类型,就会丢掉…只能返回Object类型……typeof xx ===“object”

看到called 没有?什么鬼!!

其实new关键字会创建一个空的对象,然后会自动调用一个函数apply方法,将this指向这个空对象,这样的话函数内部的this就会被这个空的对象替代。

var a={
name:"andy",
site:"zhoulujun.cn",
fn:function(age){
console.log(this.name+age);
}
};
var b={
name:"zhoulujun",
site:"www.zhoulujun.cn",
fn:function(age){
console.log(this.name+age);
}
};
a.fn(2); //andy2
a.fn.call(b,2) //zhoulujun2
a.fn.apply(b,[2])//zhoulujun2
当然,还有bind……
var arr = [1, 2];
var add = Array.prototype.push.bind(arr, 3);
// effectively the same as arr.push(3)
add();
// effectively the same as arr.push(3, 4)
add(4);
console.log(arr);
// <- [1, 2, 3, 3, 4]
在下面的例子,this将无法在作用域链中保持不变。这是规则的缺陷,并且常常会给业余开发者带来困惑。
function scoping () {
console.log(this);
return function () {
console.log(this);
};
}
scoping()();
// <- Window
// <- Window
有一个常见的方法,创建一个局部变量保持对this的引用,并且在子作用域中不能有同命变量。子作用域中的同名变量将覆盖父作用域中对this的引用。
function retaining () {
var self = this;
return function () {
console.log(self);
};
}
retaining()();
// <- Window
除非你真的想同时使用父作用域的this,以及当前this值,由于某些莫名其妙的原因,我更喜欢是使用的方法.bind函数。这可以用来将父作用域的this指定给子作用域。
function bound () {
return function () {
console.log(this);
}.bind(this);
}
bound()();
// <- Window
ログイン後にコピー

写到这里,都看不下去,逻辑有点混乱,有的是从前辈哪里引用的。

改天有时间整理下,然后,在去讲下闭包(……closer





以上がJavaScript のこのポインターについての深い理解の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、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)

WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 Dec 17, 2023 pm 02:54 PM

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

推奨: 優れた JS オープンソースの顔検出および認識プロジェクト 推奨: 優れた JS オープンソースの顔検出および認識プロジェクト Apr 03, 2024 am 11:55 AM

顔の検出および認識テクノロジーは、すでに比較的成熟しており、広く使用されているテクノロジーです。現在、最も広く使用されているインターネット アプリケーション言語は JS ですが、Web フロントエンドでの顔検出と認識の実装には、バックエンドの顔認識と比較して利点と欠点があります。利点としては、ネットワーク インタラクションの削減とリアルタイム認識により、ユーザーの待ち時間が大幅に短縮され、ユーザー エクスペリエンスが向上することが挙げられます。欠点としては、モデル サイズによって制限されるため、精度も制限されることが挙げられます。 js を使用して Web 上に顔検出を実装するにはどうすればよいですか? Web 上で顔認識を実装するには、JavaScript、HTML、CSS、WebRTC など、関連するプログラミング言語とテクノロジに精通している必要があります。同時に、関連するコンピューター ビジョンと人工知能テクノロジーを習得する必要もあります。 Web 側の設計により、次の点に注意してください。

株価分析に必須のツール: PHP と JS を使用してローソク足チャートを描画する手順を学びます 株価分析に必須のツール: PHP と JS を使用してローソク足チャートを描画する手順を学びます Dec 17, 2023 pm 06:55 PM

株式分析に必須のツール: PHP および JS でローソク足チャートを描画する手順を学びます。特定のコード例が必要です。インターネットとテクノロジーの急速な発展に伴い、株式取引は多くの投資家にとって重要な方法の 1 つになりました。株価分析は投資家の意思決定の重要な部分であり、ローソク足チャートはテクニカル分析で広く使用されています。 PHP と JS を使用してローソク足チャートを描画する方法を学ぶと、投資家がより適切な意思決定を行うのに役立つ、より直感的な情報が得られます。ローソク足チャートとは、株価をローソク足の形で表示するテクニカルチャートです。株価を示しています

WebSocket と JavaScript: リアルタイム監視システムを実装するための主要テクノロジー WebSocket と JavaScript: リアルタイム監視システムを実装するための主要テクノロジー Dec 17, 2023 pm 05:30 PM

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

JavaScript と WebSocket を使用してリアルタイムのオンライン注文システムを実装する方法 JavaScript と WebSocket を使用してリアルタイムのオンライン注文システムを実装する方法 Dec 17, 2023 pm 12:09 PM

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

PHP および JS 開発のヒント: 株価ローソク足チャートの描画方法をマスターする PHP および JS 開発のヒント: 株価ローソク足チャートの描画方法をマスターする Dec 18, 2023 pm 03:39 PM

インターネット金融の急速な発展に伴い、株式投資を選択する人がますます増えています。株式取引では、ローソク足チャートは一般的に使用されるテクニカル分析手法であり、株価の変化傾向を示し、投資家がより正確な意思決定を行うのに役立ちます。この記事では、PHP と JS の開発スキルを紹介し、株価ローソク足チャートの描画方法を読者に理解してもらい、具体的なコード例を示します。 1. 株のローソク足チャートを理解する 株のローソク足チャートの描き方を紹介する前に、まずローソク足チャートとは何かを理解する必要があります。ローソク足チャートは日本人が開発した

JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 Dec 17, 2023 pm 05:13 PM

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

簡単な JavaScript チュートリアル: HTTP ステータス コードを取得する方法 簡単な JavaScript チュートリアル: HTTP ステータス コードを取得する方法 Jan 05, 2024 pm 06:08 PM

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

See all articles