JavaScript コンストラクターと new 演算子 (重要なポイント、必読)

亚连
リリース: 2018-05-19 09:25:42
オリジナル
1650 人が閲覧しました

この記事では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
ログイン後にコピー

2. コードの解釈

1 行目から 3 行目は、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");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

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

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) )

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 メソッドを検索します。見つからない場合は、プロトタイプ チェーンに沿って検索します。プロトタイプチェーンメソッド。

さらに、sayメソッドでもthis.nameにアクセスしますが、ここでは呼び出し元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中的继承,而不仅仅是实例化了一个对象!

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

JS保留一位数字后移除非数字

JS DOM元素常见增删改查操作详解

JS保留两位小数输入数校验代码

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

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート