this this がグローバル スコープで使用される場合、this は現在のページ オブジェクト ウィンドウを参照します。this が関数で使用される場合、this が参照するものは this に基づきます。実行時に呼び出されるオブジェクト。 また、2 つのグローバル メソッド apply と call を使用して、関数内の this の特定のポインタを変更することもできます。
まず、これをグローバル スコープで使用する例を見てみましょう:
関数内のこれは、次のように関数の定義時ではなく実行時に決定されます。
foo() {
console.log(.フルーツ);
フルーツ = ;
foo();
フルーツ: ,
foo
}; );
グローバル関数の適用と呼び出しを使用して、次のように関数内の this のポインターを変更できます:
コードをコピー
コードは次のとおりです: foo() { console.log(.fruit); >pack = { フルーツ:
};
foo.apply(window);
注:と call 関数の効果は同じです。唯一の違いは、2 つの関数のパラメータ定義が異なることです
。
関数も JavaScript のオブジェクトであるため、次の興味深い例がわかります。
コードをコピー
コードは次のとおりです。 :
console.log();
} ( === window) {
console.log();
}; 🎜 >foo();
foo.boo();
プロトタイプ
プロトタイプは本質的にJavaScript オブジェクト。 そして、すべての関数にはデフォルトのプロトタイプ属性があります。
この関数がカスタム オブジェクトを作成するシナリオで使用される場合、この関数をコンストラクターと呼びます。 たとえば、次は単純なシナリオです:
コードをコピー
コードは次のとおりです:
人(名前) {
.name = 名前;
}
例として、JavaScript のデータ型 (String、Number、Array )、Object を考えてみましょう。 、日付など。 これらの型は、次のような JavaScript 内のコンストラクターとして実装されていると考える理由があります。
Array() {
}
arr1 = Array(1, 56, 34, 12); [1, 56, 34, 12];
配列を操作する多くのメソッド (concat、join、push など) も、prototype 属性で定義する必要があります。
実際、JavaScript のすべての組み込みデータ型には読み取り専用のプロトタイプ属性があります (これは理解できます。これらの型のプロトタイプ属性が変更されると、事前定義されたメソッドが消滅するためです)。しかし、それに独自の拡張メソッドを追加することができます。 。
Array.prototype.min = () {
min = [0];
( i = 1; i ([i] min = [i];
}
min;
console.log([1, 56, 34, 12]); 🎜>注意: ここには罠があります。配列のプロトタイプに拡張メソッドを追加した後、for-in を使用して配列をループすると、この拡張メソッドもループアウトされます。
次のコードは、これを示しています (min メソッドが Array プロトタイプに拡張されていると仮定しています)。
arr = [1, 56, 34, 12];
total = 0; arr) {
total = parseInt(arr[i], 10);
}
console.log(total);
解決策も非常に簡単です:
arr = [1, 56 , 34, 12];
合計 = 0;
(i arr) {
(arr.hasOwnProperty(i)) {
合計 = parseInt(arr[i], 10); 🎜 >}
}
console.log(total);
constructor
constructor は常に現在のオブジェクトを作成したコンストラクターを指します。たとえば、次の例:
コードをコピーします
コードは次のとおりです:
arr = [1, 56, 34, 12];
console.log(arr.constructor === Array);
Foo = ()
console.log (Foo.constructor === 関数);
obj = Foo();
console.log(obj.constructor === Foo); Function);
しかし、コンストラクターがプロトタイプに遭遇すると、興味深いことが起こります。
各関数にはデフォルトの属性プロトタイプがあり、このプロトタイプのコンストラクターはデフォルトでこの関数を指すことがわかっています。次の例に示すように:
person(名前) {
.name = 名前;
.prototype.getName = () {
.name;
; >console.log( p.constructor === 人);
console.log(人.prototype.constructor === 人);
console.log(p.constructor.prototype.constructor === 人);
関数のプロトタイプを再定義したとき (注: 上記の例との違い、これは変更ではなくオーバーライドです)、コンストラクターの動作は少し奇妙でした。次の例に示します:
コードをコピー
person.prototype = {
getName: () {
}
}; = 人();
console.log(p.constructor = == 人);
console.log(p.constructor. prototype.constructor === 人);
なぜですか?
Person.prototype を上書きすると、次のコード操作と同等であることがわかります:
コードをコピー
コードは次のとおりです:
person.prototype = Object({ getName: () { .name; } }); > while コンストラクター 常に自分自身を作成するコンストラクターを指すため、この時点では person.prototype.constructor === オブジェクト、つまり:
コードをコピー
コードは以下のとおりです。 🎜>getName: () {
;
}
console.log(p.constructor === オブジェクト); console.log(person.prototype.constructor == = Object);
コードをコピー
コードは次のとおりです。
人(名前) {
.name = 名前;
};
人.prototype = Object({
getName: () {
.name ;
}
});
person.prototype.constructor = 人;
console.log(p.constructor === 人); console.log(人。prototype.constructor === 人);
console.log(p.constructor.prototype.constructor === 人);