これは何ですか? JavaScript でのこれの詳細な分析
###これは何ですか?次の記事では、JavaScript でのこれについて説明し、関数の呼び出し方法の違いによる違いについて説明します。 JavaScript
の
this
は、
Java 言語の
this# など、特に異なります。 ## はコードの実行フェーズでは変更できませんが、JavaScript の this
は 呼び出しフェーズ
でバインドされます。この性質により、this には多くの開発の余地が与えられます。ただし、厳密モードと非厳密モードでは多少異なります。また、関数の呼び出し方法の違いにより、これにもいくつかの違いが生じます。 #########これは何ですか?
これは、実行コンテキストの作成時に決定される変数で、実行中に変更することはできません。
いわゆる実行コンテキストは、コードを実行する前にいくつかの 変数
と関数を使用する JavaScript エンジンです。 , this事前に宣言して変数オブジェクトに格納する処理。この「コード スニペット」には、グローバル コード (スクリプト タグ内のコード)、関数内部コード、eval 内部コードが含まれます。私たちがよく知っているスコープ チェーンもここに保存され、対応する関数の [[Scopes]] 属性に配列のような形式で保存されます。 これは、関数呼び出しフェーズ中にのみ決定されます。つまり、実行コンテキストが作成されると、変数オブジェクトに割り当てられて保存されます。この機能は this の可変性にもつながります。つまり、関数が異なる方法で呼び出されるとき、this の値は異なる可能性があります。 これは厳密モードと非厳密モードで動作が異なると上で述べました:
var a = 1; function fun() { 'use strict'; var a = 2; return this.a; } fun();//报错 Cannot read property 'a' of undefined
var a = 1; function fun() { var a = 2; return this.a; } fun();//1
- 上記の同じコード部分は、モードが異なると動作が異なります。厳密モードと非厳密モードでは異なります。 結論: 関数が独立して呼び出された場合、厳密モードでは this は undefined を指しますが、非厳密モードでは、this が unknown を指すと、自動的にグローバル オブジェクトを指します (つまり、ブラウザ ウィンドウ)
this.a = 1; var b = 1; c = 1; console.log(this === window)//true //这三种都能得到想要的结果,全局上下文的变量对象中存在这三个变量
var a = 1000; var obj = { a: 1, b: this.a + 1 } function fun() { var obj = { a: 1, c: this.a + 2 //严格模式下这块报错 Cannot read property 'a' of undefined } return obj.c; } console.log(fun());//1002 console.log(obj.b);//1001
obj がグローバルに宣言されている場合、obj の内部プロパティの this はグローバル オブジェクトを指します。obj が関数で宣言されている場合、厳密モードでは、これはポイントします未定義の非厳密モードに変更すると、グローバル オブジェクトを指すように自動的に変更されます。
わかりました。実際に試してみました。厳密モードと非厳密モードの違いはわかりました。ただし、日常生活で最も一般的な使用法は、これを次のように使用することです。上でも触れましたが、関数の呼び出し方法には違いがあります。 4 種類:グローバル環境内のオブジェクトのメソッドまたは通常の関数
を直接呼び出す
- apply と call
- をそのまま使用するコンストラクター関数
- は、次の 4 つの状況で展開されます。
- 直接呼び出し
var a = 1;
var obj = {
a: 2,
b: function () {
function fun() {
return this.a
}
console.log(fun());
}
}
obj.b();//1
ログイン後にコピー
fun 関数は obj.b メソッドで定義されていますが、これはまだ通常の関数です。直接呼び出すと、非厳密モードで未定義を指し、自動的に期待どおり、グローバル オブジェクトを指します。厳密モードでは、エラー「unknown.a が確立されていません、a が定義されていません」が報告されます。
もう一度言っておきたい重要なこと: var a = 1; var obj = { a: 2, b: function () { function fun() { return this.a } console.log(fun()); } } obj.b();//1
関数が独立して呼び出されるとき、厳密モードでは this は未定義を指します。非厳密モードでは、this が undefend を指すと、自動的にグローバル オブジェクトを指します。 (ブラウザではウィンドウです)。
オブジェクトのメソッドとして
var a = 1; var obj = { a: 2, b: function() { return this.a; } } console.log(obj.b())//2
var a = 1;
var obj = {
a: 2,
b: function() {
return this.a;
}
}
var t = obj.b;
console.log(t());//1
ログイン後にコピー
上記のように、t 関数の実行結果はグローバル変数 1 になります。これには Javascript のメモリ空間が関係します。つまり、obj オブジェクトの b 属性には、ポインタとして理解できる無名関数への参照が格納されます。 t に値を割り当てる場合、新しい関数を格納するための別のメモリ空間は開かれず、代わりに t はこの関数を指すポインタを格納します。これは、次のような疑似コードを実行するのと同じです: var a = 1;
function fun() {//此函数存储在堆中
return this.a;
}
var obj = {
a: 2,
b: fun //b指向fun函数
}
var t = fun;//变量t指向fun函数
console.log(t());//1
ログイン後にコピー
このとき、 t は fun 関数へのポインタです。 t を呼び出すことは、 fun を直接呼び出すことと同じです。 上記のルールを適用すると、 1 が出力されます。自然に分かりやすくなります。
var a = 1; var obj = { a: 2, b: function() { return this.a; } } var t = obj.b; console.log(t());//1
var a = 1; function fun() {//此函数存储在堆中 return this.a; } var obj = { a: 2, b: fun //b指向fun函数 } var t = fun;//变量t指向fun函数 console.log(t());//1
使用apply,call
关于apply和call是干什么的怎么用本文不涉及,请移驾:apply,call
这是个万能公式,实际上上面直接调用的代码,我们可以看成这样的:
function fun() { return this.a; } fun();//1 //严格模式 fun.call(undefined) //非严格模式 fun.call(window)
这时候我们就可以解释下,为啥说在非严格模式下,当函数this指向undefined的时候,会自动指向全局对象,如上,在非严格模式下,当调用fun.call(undefined)的时候打印出来的依旧是1,就是最好的证据。
为啥说是万能公式呢?再看函数作为对象的方法调用:
var a = 1; var obj = { a: 2, b: function() { return this.a; } } obj.b() obj.b.call(obj)
如上,是不是很强大,可以理解为其它两种都是这个方法的语法糖罢了,那么apply和call是不是真的万能的呢?并不是,ES6的箭头函数就是特例,因为箭头函数的this不是在调用时候确定的,这也就是为啥说箭头函数好用的原因之一,因为它的this固定不会变来变去的了。关于箭头函数的this我们稍后再说。
作为构造函数
何为构造函数?所谓构造函数就是用来new对象的函数,像Function
、Object
、Array
、Date
等都是全局定义的构造函数。其实每一个函数都可以new对象,那些批量生产我们需要的对象的函数就叫它构造函数罢了。注意,构造函数首字母记得大写。
function Fun() { this.name = 'Damonre'; this.age = 21; this.sex = 'man'; this.run = function () { return this.name + '正在跑步'; } } Fun.prototype = { contructor: Fun, say: function () { return this.name + '正在说话'; } } var f = new Fun(); f.run();//Damonare正在跑步 f.say();//Damonare正在说话
如上,如果函数作为构造函数用,那么其中的this就代表它即将new出来的对象。为啥呢?new做了啥呢?
伪代码如下:
function Fun() { //new做的事情 var obj = {}; obj.__proto__ = Fun.prototype;//Base为构造函数 obj.name = 'Damonare'; ...//一系列赋值以及更多的事 return obj }
也就是说new做了下面这些事:
- 创建一个临时对象
- 给临时对象绑定原型
- 给临时对象对应属性赋值
- 将临时对象return
也就是说new其实就是个语法糖,this之所以指向临时对象还是没逃脱上面说的几种情况。
当然如果直接调用Fun(),如下:
function Fun() { this.name = 'Damonre'; this.age = 21; this.sex = 'man'; this.run = function () { return this.name + '正在跑步'; } } Fun(); console.log(window)
其实就是直接调用一个函数,this在非严格模式下指向window,你可以在window对象找到所有的变量。
另外还有一点,prototype对象的方法的this指向实例对象,因为实例对象的__proto__
已经指向了原型函数的prototype。这就涉及原型链的知识了,即方法会沿着对象的原型链进行查找。
箭头函数
刚刚提到了箭头函数是一个不可以用call和apply改变this的典型。
我们看下面这个例子:
var a = 1; var obj = { a: 2 }; var fun = () => console.log(this.a); fun();//1 fun.call(obj)//1
以上,两次调用都是1。
那么箭头函数的this是怎么确定的呢?箭头函数会捕获其所在上下文的 this
值,作为自己的 this
值,也就是说箭头函数的this在词法层面就完成了绑定。apply,call方法只是传入参数,却改不了this。
var a = 1; var obj = { a: 2 }; function fun() { var a = 3; let f = () => console.log(this.a); f(); }; fun();//1 fun.call(obj);//2
如上,fun直接调用,fun的上下文中的this值为window,注意,这个地方有点绕。fun的上下文就是此箭头函数所在的上下文,因此此时f的this为fun的this也就是window。当fun.call(obj)再次调用的时候,新的上下文创建,fun此时的this为obj,也就是箭头函数的this值。
再来一个例子:
function Fun() { this.name = 'Damonare'; } Fun.prototype.say = () => { console.log(this); } var f = new Fun(); f.say();//window
有的同学看到这个例子会很懵逼,感觉上this应该指向f这个实例对象啊。不是的,此时的箭头函数所在的上下文是__proto__
所在的上下文也就是Object函数的上下文,而Object的this值就是全局对象。
那么再来一个例子:
function Fun() { this.name = 'Damonare'; this.say = () => { console.log(this); } } var f = new Fun(); f.say();//Fun的实例对象
如上,this.say所在的上下文,此时箭头函数所在的上下文就变成了Fun的上下文环境,而因为上面说过当函数作为构造函数调用的时候(也就是new的作用)上下文环境的this指向实例对象。
【相关推荐:javascript学习教程】
以上がこれは何ですか? 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テクノロジー

WebSocket と JavaScript を使用してオンライン予約システムを実装する方法 今日のデジタル時代では、ますます多くの企業やサービスがオンライン予約機能を提供する必要があります。効率的かつリアルタイムのオンライン予約システムを実装することが重要です。この記事では、WebSocket と JavaScript を使用してオンライン予約システムを実装する方法と、具体的なコード例を紹介します。 1. WebSocket とは何ですか? WebSocket は、単一の TCP 接続における全二重方式です。

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

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

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

使用法: JavaScript では、insertBefore() メソッドを使用して、DOM ツリーに新しいノードを挿入します。このメソッドには、挿入される新しいノードと参照ノード (つまり、新しいノードが挿入されるノード) の 2 つのパラメータが必要です。

JavaScript で HTTP ステータス コードを取得する方法の紹介: フロントエンド開発では、バックエンド インターフェイスとの対話を処理する必要があることが多く、HTTP ステータス コードはその非常に重要な部分です。 HTTP ステータス コードを理解して取得すると、インターフェイスから返されたデータをより適切に処理できるようになります。この記事では、JavaScript を使用して HTTP ステータス コードを取得する方法と、具体的なコード例を紹介します。 1. HTTP ステータス コードとは何ですか? HTTP ステータス コードとは、ブラウザがサーバーへのリクエストを開始したときに、サービスが
