ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript コンストラクターと new 演算子の紹介例

JavaScript コンストラクターと new 演算子の紹介例

黄舟
黄舟オリジナル
2017-08-22 11:13:301029ブラウズ

この記事ではJavaScriptのコンストラクターとnew演算子を中心に、new演算子の理解、コード解釈、キー解析、newの意味、概要などを総合的に紹介しています。具体的な操作手順については以下の詳細説明をご覧ください。 、興味のある友人はそれを参照できます。

JS の関数は、コンストラクターにすることも、通常の関数として呼び出すこともできます。 new を使用してオブジェクトを作成する場合、対応する関数はコンストラクターであり、オブジェクトを通じて呼び出される場合、それは通常の関数です。

通常の関数を作成するには、明示的な宣言、匿名定義、new Function() の 3 つの方法があります。

new を通じて新しいオブジェクトが作成されると、JS の最下層は新しいオブジェクトのプロトタイプ チェーンをコンストラクターのプロトタイプ オブジェクトにポイントするため、新しいオブジェクトと関数オブジェクトの間にプロトタイプ チェーンが確立されます。関数オブジェクト プロトタイプ プロトタイプの新しいオブジェクト メソッドとプロパティを通じてアクセスします。

他の高級言語と同様に、JavaScript にもコンストラクターと new 演算子があり、クラスをインスタンス化し、メモリ内にインスタンス オブジェクトを割り当てるために new が使用されることがわかっています。 しかし、JavaScript ではすべてがオブジェクトです。オブジェクトを生成するために new を使用する必要があるのはなぜでしょうか。 この記事では、JavaScript の new の謎を探ります

1. new 演算子を理解する


function Animal(name){
this.name = name;
}
 Animal.color = "black";
 Animal.prototype.say = function(){
console.log("I'm " + this.name);
 };
 var cat = new Animal("cat");

 console.log(
 cat.name, //cat
 cat.color //undefined
 );
 cat.say(); //I'm cat

 console.log(
 Animal.name, //Animal
 Animal.color //back
 );
 Animal.say(); //Animal.say is not a function

行 1 ~ 3 は、 function Animal を定義し、これに属性 name を定義します。 name の値は、関数が実行されるときの仮パラメータです。 4 行目は、Animal オブジェクトの color という静的プロパティを定義し (Animal 自体は関数オブジェクトです)、値「black」を割り当てます

5-7 行目は、Animal 関数のプロトタイプ オブジェクト プロトタイプの Say() を定義していますメソッドの場合、say メソッドは this の名前の値を出力します。

8 行目では、new キーワードを使用して新しいオブジェクト cat を作成します。

10 ~ 14 行目 cat オブジェクトは、name 属性と color 属性へのアクセスを試み、say メソッドを呼び出します。

16 ~ 20 行目で、Animal オブジェクトは名前と色のプロパティにアクセスしようとして、say メソッドを呼び出します。

3. キー分析

コードの 8 行目がキーです: var cat = new Animal("cat");

Animal 自体は通常の関数です, ただし、new を通じてオブジェクトを作成する場合、Animal がコンストラクターになります。

var cat = new Animal("cat");

Animal 本身是一个普通函数,但当通过new来创建对象时,Animal就是构造函数。

JS引擎执行这句代码时,在内部做了很多工作,用伪代码模拟其工作流程如下:


new Animal("cat") = {

var obj = {};

obj.__proto__ = Animal.prototype;

var result = Animal.call(obj,"cat");

return typeof result === 'object'? result : obj;
}

(1)创建一个空对象obj;

(2)把obj的proto指向构造函数Animal的原型对象prototype,此时便建立了obj对象的原型链:obj->Animal.prototype->Object.prototype->null

(3)在obj对象的执行环境调用Animal 函数并传递参数“cat”。 相当于var result = obj.Animal(“cat”)。

(4)考察第3步返回的返回值,如果无返回值或者返回一个非对象值,则将obj返回作为新对象;否则会将返回值作为新对象返回。

理解了其运行机制以后,我们知道cat其实就是过程(4)的返回值,因此我们对cat对象的认知就多了一些:

cat的原型链是:cat->Animal.prototype->Object.prototype->null<br>JS エンジンがこのコードを実行すると、内部で多くの作業が実行され、次のようにワークフローをシミュレートするために疑似コードが使用されます:


var L = A.__proto__;
var R = B.prototype;
if(L === R)
return true;

(1)

空のオブジェクト obj;

を作成します。 (2)

obj の proto をコンストラクター関数 Animal のプロトタイプ オブジェクトのプロトタイプにポイントします。このとき、obj オブジェクトのプロトタイプ チェーンが確立されます。 obj->Animal.prototype->Object.prototype-> null

(3)

In obj オブジェクトの実行環境は、Animal 関数を呼び出し、パラメータ「cat」を渡します。 var result = obj.Animal("cat") と同等です。

(4)

手順 3 で返された戻り値を確認します。戻り値がない場合、またはオブジェクト以外の値が返された場合は、obj が新しいオブジェクトとして返されます。それ以外の場合、戻り値は として返されます。新しいオブジェクト。

その動作メカニズムを理解すると、cat が実際にはプロセス (4) の戻り値であることがわかり、cat オブジェクトについてさらに詳しく知ることができます。

cat のプロトタイプ チェーンは次のとおりです: cat->Animal.prototype- >Object.prototype->null


cat には新しい属性があります: name


cat の生成プロセスを分析した後、出力結果を見てみましょう:

cat name -> ; プロセス (3) では、obj オブジェクトが name 属性を生成します。したがって、cat.name はここでの obj.name です

cat.color -> cat は最初に独自の色を検索し、見つからない場合はプロトタイプ チェーンに沿って検索します。上記の例では、定義しただけです。 Animal オブジェクトの color は、そのプロトタイプ チェーンで定義されていないため、見つかりません。 cat.say -> cat は、最初に独自の Say メソッドを検索します。見つからない場合は、プロトタイプ チェーンに沿って検索します。上の例では、Animal プロトタイプで Say を定義しました。プロトタイプチェーンメソッド。 さらに、this.nameはsayメソッドでもアクセスされますが、ここでは呼び出し元objを参照しているため、obj.nameの値が出力されます。

🎜Animal の場合、それ自体がオブジェクトでもあるため、プロパティやメソッドにアクセスする際にも上記の検索ルールに従います: 🎜🎜Animal.color -> "black"🎜🎜Animal.name -> , Animal はまず自分自身の名前を検索して名前を見つけますが、この名前は定義した名前ではなく、関数オブジェクトの組み込みプロパティです。 🎜🎜通常、関数オブジェクトが生成されると、組み込みの name 属性があり、関数名を代入値として使用します (関数オブジェクトのみ)。 🎜🎜Animal.say -> Animal はそれ自体では Say メソッドを見つけず、そのプロトタイプ チェーンに沿って検索します。 Animal のプロトタイプ チェーンとは何ですか? 🎜🎜テスト結果から: Animal のプロトタイプ チェーンは次のとおりです: 🎜🎜🎜Animal->Function.prototype->Object.prototype->null 🎜🎜🎜つまり、Animal のプロトタイプ チェーンには Say メソッドは定義されていません。 🎜🎜🎜🎜4. Newの存在意義🎜🎜🎜

认识了new运算符之后,我们再回到开篇提到的问题:JS中万物皆对象,为什么还要通过new来产生对象?

要弄明白这个问题,我们首先要搞清楚cat和Animal的关系:

通过上面的分析,我们发现cat继承了Animal中的部分属性,因此我们可以简单的理解:Animal和cat是继承关系。

另一方面,cat是通过new产生的对象,那么cat到底是不是Animal的实例对象? 我们先来了解一下JS是如何来定义“实例对象”的?

A instanceof B
如果上述表达式为true,JS认为A是B的实例对象,我们用这个方法来判断一下cat和Animal

cat instanceof Animal; //true
从执行结果看:cat确实是Animal实例,要想证实这个结果,我们再来了解一下JS中instanceof的判断规则:


var L = A.__proto__;
var R = B.prototype;
if(L === R)
return true;

如果A的proto 等价于 B的prototype,就返回true

在new的执行过程(2)中,cat的proto指向了Animal的prototype,所以cat和Animal符合instanceof的判断结果。

因此,我们认为:cat 是Animal的实例对象。

5、总结

在Javascript中, 通过new可以产生原对象的一个实例对象,而这个实例对象继承了原对象的属性和方法。因此,new存在的意义在于它实现了Javascript中的继承,而不仅仅是实例化了一个对象!

以上がJavaScript コンストラクターと new 演算子の紹介例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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