ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScriptのthis・call・applyの使い方と違いを詳しく解説

JavaScriptのthis・call・applyの使い方と違いを詳しく解説

PHPz
PHPzオリジナル
2016-05-16 15:17:091253ブラウズ

以前 JavaScript を学習したとき、this、call、apply はいつも混乱しましたが、これらは広く使用されています。ということで、JavaScriptのthisを理解し、呼び出し、適用するのに丸一日を費やしました。

途中で参考にした本もたくさんありますが、主に「JavaScript の設計パターンと開発実践」に、「JavaScript 高度なプログラミング」と「あなたの知らない JavaScript」が補足されています。この 3 冊の本は、これを理解し、呼びかけ、応用するのに非常に役立ちました。

まず、これについて話しましょう。

『JavaScriptのデザインパターンと開発実践』のこれについての説明の中に、これの核心を突いている一文があると思います。つまり、

JavaScript では This は常にオブジェクトを指します
実際のアプリケーションでは、this の指すことは次の 4 つのタイプに分類できます。

  1. Asオブジェクトメソッドは、通常の関数呼び出しとして

  2. を呼び出します。

  3. コンストラクターは

  4. を呼び出します。 apply および call

を呼び出します。 🎜>

次に、最初の 3 つのポイントを分析します。4 番目のポイントの apply と call については、call と apply のセクションで詳しく説明します。

1. オブジェクト メソッドとしての呼び出し

説明: オブジェクト メソッドとして呼び出す場合、これはオブジェクトを指します。
/**
 * 1.作为对象的方法调用
 *
 * 作为对象方法调用时,this指向该对象。
 */

var obj = {
 a: 1,
 getA: function() {
  console.log(this === obj);
  console.log(this.a);
 }
};

obj.getA(); // true , 1
例:

2. 通常の関数として呼び出される

注: 通常の関数として呼び出される場合、これは常にグローバル オブジェクト (ブラウザのウィンドウ) を指します。
/**
 * 2.作为普通函数调用
 *
 * 不作为对象属性调用时,this必须指向一个对象。那就是全局对象。
 */

window.name = 'globalName';

var getName = function() {
 console.log(this.name);
};

getName(); // 'globalName'

var myObject = {
 name: "ObjectName",
 getName: function() {
  console.log(this.name)
 }
};

myObject.getName(); // 'ObjectName'

// 这里实质上是把function() {console.log(this.name)}
// 这句话赋值给了theName。thisName在全局对象中调用,自然读取的是全局对象的name值
var theName = myObject.getName;

theName(); // 'globalName'
例:

3. コンストラクター呼び出し

説明: コンストラクターとして呼び出された場合、これは返されたものを指します。物体。
/**
 * 3.作为构造器调用
 * 
 * 作为构造器调用时,this指向返回的这个对象。
 */

var myClass = function() {
 this.name = "Lxxyx";
};

var obj = new myClass();

console.log(obj.name); // Lxxyx
console.log(obj) // myClass {name: "Lxxyx"}
例:


ただし、返される他のオブジェクトがコンストラクターで手動で指定されている場合、これは機能しません。
var myClass = function() {
 this.name = "Lxxyx";
 // 加入return时,则返回的是别的对象。this不起作用。
 return {
  name:"ReturnOthers"
 }
};

var obj = new myClass();
console.log(obj.name); // ReturnOthers
返されたデータ型が別のデータ型の場合は問題ありません。

4. 電話と申し込み

電話と申し込みは同じ目的です。これらはすべて、関数本体で this のポインタを指定するために使用されます。

Call と apply の違い

Call: 最初のパラメータはこれへのポインタであり、関数に渡すパラメータは 1 つずつ入力する必要があります。

適用: 最初のパラメータはこれへのポインタ、2 番目のパラメータは配列で、すべてのパラメータが一度に渡されます。

最初のパラメータが null の場合、これは呼び出し自体を指します。


1. これを

を指すように変更します。 説明: これは、call と apply の最も一般的な使用法です。関数本体内の this のポインタを変更するために使用されます。
var name = "GlobalName"

var func = function() {
 console.log(this.name)
};

func(); // "GlobalName"

var obj = {
 name: "Lxxyx",
 getName: function() {
  console.log(this.name)
 }
};

obj.getName.apply(window) // "GlobalName" 将this指向window
func.apply(obj) // "Lxxyx" 将this指向obj
例:

2. 他のオブジェクトからメソッドを借用する
(function(a, b) {
 console.log(arguments) // 1,2
 // 调用Array的原型方法
 Array.prototype.push.call(arguments, 3);
 console.log(arguments) // 1,2,3
})(1,2)
ここでは、すぐに実行される匿名関数から始めます:



関数には argument 属性があり、引数は配列のような配列です。
ただし、引数で配列メソッドを直接呼び出すことはできないため、call または apply を使用して Array オブジェクトのプロトタイプ メソッドを呼び出す必要があります。
function ArrayPush() {
 var n = TO_UINT32(this.length); // 被push对象的长度
 var m = % _ArgumentsLength(); // push的参数个数
 for (var i = 0; i < m; i++) {
  this[i + n] = % _Arguments(i); // 复制元素
 }
 this.length = n + m; //修正length属性
 return this.length;
}
原理もわかりやすいです。たとえば、今呼び出したのはプッシュ メソッドです。プッシュ メソッドは、Google の v8 エンジンにあります。

これに関係しているだけなので、配列状のオブジェクトであれば関連するメソッドを呼び出して処理することができます。

この部分はかなり複雑な内容で、私もあまり得意ではありません。したがって、資格のある学生には関連書籍を購入するか、私のフォローアップ ブログ記事を待つことをお勧めします。

感想

この部分を勉強することで、JavaScript についての理解が深まりました。最も直観的な現れは、いくつかの優れたフレームワークのソース コードを見たときに、呼び出し、適用、バインドに混乱することがなくなったことです。まだとても幸せです~

次の期間では、私が毎日学習して使用している CSS を詳しく調査するつもりです。結局のところ、JavaScript を学習した後は、HTML と CSS を離れることはできません。

【おすすめ関連チュートリアル】
1. JavaScript ビデオチュートリアル
2. JavaScript オンラインマニュアル

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