JavaScript のこれは比較的柔軟です。これは、環境が異なる場合や、同じ関数が異なる方法で呼び出される場合に応じて異なる場合があります。ただし、一般原則があります。つまり、これは関数を呼び出すオブジェクトを指します。
シリーズ目次
- JavaScriptのクロージャ(Closure)を簡単に説明
- JavaScriptのこれを簡単に説明
- JavaScriptのプロトタイプチェーンと継承を簡単に説明
以下は私の勉強ノートを 8 つの状況に分けてリストします。
グローバル this (ブラウザ)
グローバル スコープ内の This は通常、ブラウザではグローバル オブジェクトを指し、ノードではこのオブジェクトはグローバルです。
console.log(this.document === document); // true (document === window.document)
console.log(this === window); // true
this.a = 37; //相当于创建了一个全局变量a
console.log(window.a); // 37
ログイン後にコピー
一般関数の This (ブラウザ)
一般関数宣言または関数式。関数が直接呼び出された場合、this は依然としてグローバル オブジェクトを指します。ブラウザでは、このオブジェクトは window であり、node では、このオブジェクトです。グローバルです。
function f1(){
return this;
}
f1() === window; // true, global object
ログイン後にコピー
別の例ですが、読むと非常に明確になります
function test(){
this.x = 1;
alert(this.x);
}
test(); // 1
ログイン後にコピー
これがグローバル オブジェクトであることを証明するために、コードにいくつかの変更を加えます:
var x = 1;
function test(){
alert(this.x);
}
test(); // 1
ログイン後にコピー
実行結果はまだ 1 です。もう一度変更します:
var x = 1;
function test(){
this.x = 0;
}
test();
alert(x); //0
ログイン後にコピー
しかし、厳密モードでは、一般関数が呼び出されるとき、これは未定義を指します。これが、ノードが厳密モードを使用する理由の 1 つです。
function f2(){
"use strict"; // see strict mode
return this;
}
f2() === undefined; // true
ログイン後にコピー
これをオブジェクト メソッドの関数として使用します
これをオブジェクト メソッドとして使用する方が一般的です。
次の例では、オブジェクトリテラルoを作成します。oには属性fがあり、その値が関数オブジェクトです。この関数をオブジェクト属性の値として使用することをオブジェクトメソッドと呼びます。オブジェクトのメソッドとして呼び出す場合、これはオブジェクト o
var o = {
prop: 37,
f: function() {
return this.prop;
}
};
console.log(o.f()); // logs 37
ログイン後にコピー
を関数リテラルのように定義する必要はありません。次の場合、independent( を呼び出す場合のみオブジェクトを定義します。直接) 関数を使用すると、これは window を指しますが、代入を通じて一時的にプロパティ f を作成し、それを関数オブジェクトに指すと、やはり 37 が得られます。
var o = {prop: 37};
function independent() {
return this.prop;
}
o.f = independent;
console.log(o.f()); // logs 37
ログイン後にコピー
つまり、関数の作成方法には依存しませんが、関数がオブジェクトのメソッドとして呼び出されている限り、これはオブジェクトを指します。
これはオブジェクト プロトタイプ チェーン上です
次の例では、最初に属性 f を持つオブジェクト o を作成し、関数はオブジェクト属性の値として使用されます。オブジェクトを介して作成しました。 .create(o) オブジェクト p、p は空のオブジェクト、そのプロトタイプは o を指し、p.a = 1; p.b = 4 を使用してオブジェクト p に属性を作成し、プロトタイプでメソッドを呼び出すと、 this.a、this.b は依然としてオブジェクト p の a と b を取得できます。
ここで注意する必要があるのは、p のプロトタイプが o であるということです。p.f() を呼び出すと、プロトタイプ チェーン o の属性 f を呼び出し、現在のオブジェクト p を取得できます。
var o = {f:function(){ return this.a + this.b; }};
var p = Object.create(o);
p.a = 1;
p.b = 4;
console.log(p.f()); // 5
ログイン後にコピー
get/setメソッドとget/setメソッドのthis
thisは通常、get/setメソッドが配置されているオブジェクトを指します
function modulus(){
return Math.sqrt(this.re * this.re + this.im * this.im);
}
var o = {
re: 1,
im: -1,
get phase(){
return Math.atan2(this.im, this.re);
}
};
Object.defineProperty(o, 'modulus', { //临时动态给o对象创建modules属性
get: modulus, enumerable:true, configurable:true});
console.log(o.phase, o.modulus); // logs -0.78 1.4142
ログイン後にコピー
コンストラクタ内のthis
newを使用してMyClassを呼び出す場合、コンストラクターでは、this は空のオブジェクトを指し、このオブジェクトのプロトタイプは MyClass.prototype を指します (プロトタイプ チェーンの概要については、この記事を参照してください)。ただし、呼び出し時には this.a = 37 が割り当てられるため、最後に this が戻り値として使用されます (return ステートメントが記述されていない場合、または return が基本型の場合は、return ステートメントが戻り値として使用されます)。2 番目の例では、return ステートメントはオブジェクトを返します。その場合、 a = 38 が戻り値として使用されます
function MyClass(){
this.a = 37;
}
var o = new MyClass();
console.log(o.a); // 37
function C2(){
this.a = 37;
return {a : 38};
}
o = new C2();
console.log(o.a); // 38
ログイン後にコピー
call/apply メソッドはこれと同じです
異なる呼び出しメソッドに加えて、関数オブジェクトの一部のメソッドは、call/apply など、関数実行のこれを変更できます。
基本的に、call と apply の間に違いはありません。ただし、call はフラットな方法でパラメーターを渡し、apply は配列を渡します。以下の例のように
どのような場合に電話を使用して申請する必要がありますか?たとえば、Object.prototype.toString を呼び出したいが、特定の this を指定したい場合は、Object.prototype.toString.call(this) を使用して、直接呼び出すことができないいくつかのメソッドを呼び出すことができます。次の例を見てみましょう:
function add(c, d){
return this.a + this.b + c + d;
}
var o = {a:1, b:3};
add.call(o, 5, 7); // 1 + 3 + 5 + 7 = 16 //第一个参数接收的是你想作为this的对象
add.apply(o, [10, 20]); // 1 + 3 + 10 + 20 = 34
function bar() {
console.log(Object.prototype.toString.call(this));
}
bar.call(7); // "[object Number]"
ログイン後にコピー
bind メソッドと this
bind メソッドは es5 から提供されているため、ie9+ のみがサポートされています
function f(){
return this.a;
}
var g = f.bind({a : "test"}); //想把某个对象作为this的时候,就把它传进去,得到一个新对象g
console.log(g()); // test //重复调用的时候,this已经指向bind参数。这对于我们绑定一次需要重复调用依然实现绑定的话,会比apply和call更加高效(看下面这个例子)
var o = {a : 37, f : f, g : g};
console.log(o.f(), o.g()); // 37, test
//o.f()通过对象的属性调用,this指向对象o;比较特殊的是即使我们把新绑定的方法作为对象的属性调用,o.g()依然会按之前的绑定去走,所以答案是test不是g
ログイン後にコピー
概要
プロジェクトを実行しているときに、これらの基本概念がいかに重要であるかを発見しました。入れないでください。 1つずつ実装すると、気をつけないと本当に落とし穴にはまってしまいます。今後、プロトタイプチェーン、スコープ、継承、チェーンコール、規則性などの知識もまとめていきますので、ぜひご注目ください
上記はJavaScriptでの詳しい説明です。 PHP 中国語 Web サイト (www.php.cn)!