この記事では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;
空のオブジェクト 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</p>
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 サイトの他の関連記事を参照してください。