ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScriptでのプロトタイプの使い方を詳しく解説

JavaScriptでのプロトタイプの使い方を詳しく解説

黄舟
黄舟オリジナル
2017-11-23 10:19:311945ブラウズ

JavaScript を使用したことのある多くの友人はプロトタイプについてある程度理解していると思いますが、初心者にとってプロトタイプとは何なのか、関数にはプロトタイプ属性があり、たとえば Access で関数を追加できることしか知りません。残りについてはわかりません。今日は JavaScript でのプロトタイプの詳細な使い方を紹介します。

JavaScript を使用したことのある学生はプロトタイプに精通しているはずですが、初心者は関数にプロトタイプ属性があることと、アクセスなどの関数を追加できることだけを知っており、その他は明確ではありません。高度な JavaScript プログラミングをいくつか体験し、ついにその謎を明らかにしました。

各関数には、オブジェクトへの参照であるプロトタイプ属性があります。このオブジェクトは、プロトタイプ オブジェクトと呼ばれます。プロトタイプ オブジェクトには、関数インスタンスによって共有されるメソッドとプロパティが含まれます。これは、関数が コンストラクター 呼び出しとして使用されることを意味します。 (new 演算子を使用して呼び出された場合)、新しく作成されたオブジェクトは、プロトタイプ オブジェクトからプロパティとメソッドを継承します。

プライベート変数と関数

プロトタイプについて詳しく話す前に、プロトタイプの設計意図をよりよく理解できるように、関連するいくつかのことについて話しましょう。以前に書いた JavaScript 名前空間 の記事では、JavaScript の 関数スコープ について言及しました。関数内で定義された変数と関数が外部の世界へのインターフェイスを提供しない場合、それらは外部の世界にアクセスできなくなります。プライベート変数とプライベート関数になります。

コードは次のとおりです:

function Obj(){
                var a=0; //私有变量
                var fn=function(){ //私有函数
                }
            }

このように、変数 a と関数 fn は関数オブジェクト Obj の外部ではアクセスできなくなり、関数 Obj のインスタンスであってもこれらにアクセスすることはできなくなります。変数と関数

コードは次のとおりです:

var o=new Obj();
            console.log(o.a); //undefined
            console.log(o.fn); //undefined

静的変数、関数

関数を定義する場合、「.」を通じてそれに追加されたプロパティと関数には、オブジェクト自体を通じてアクセスできます。ただし、そのインスタンスにはアクセスできません。このような変数と関数は、それぞれ静的変数と静的関数と呼ばれます。Java と C# を使用したことのある学生は、静的の意味を簡単に理解できます。

コードは次のとおりです:

function Obj(){
            }
            Obj.a=0; //静态变量
            Obj.fn=function(){ //静态函数
            }
            console.log(Obj.a); //0
            console.log(typeof Obj.fn); //function
            var o=new Obj();
            console.log(o.a); //undefined
            console.log(typeof o.fn); //undefined

インスタンス変数、関数

オブジェクト指向プログラミングでは、いくつかのライブラリ関数に加えて、いくつかのプロパティとメソッドを同時に定義したいと考えています。 JavaScript のインスタンス化後にアクセスできるオブジェクトが定義されています。このようにすることもできます

コードは次のとおりです:

function Obj(){
                this.a=[]; //实例变量
                this.fn=function(){ //实例方法
                }
            }
            console.log(typeof Obj.a); //undefined
            console.log(typeof Obj.fn); //undefined
            var o=new Obj();
            console.log(typeof o.a); //object
            console.log(typeof o.fn); //function

これで上記の目的は達成できますが、

コードは次のとおりです:

function Obj(){
                this.a=[]; //实例变量
                this.fn=function(){ //实例方法
                }
            }
            var o1=new Obj();
            o1.a.push(1);
            o1.fn={};
            console.log(o1.a); //[1]
            console.log(typeof o1.fn); //object
            var o2=new Obj();
            console.log(o2.a); //[]
            console.log(typeof o2.fn); //function

上記のコードの実行結果は完全に期待どおりですが、A は o1 と fn で変更されましたが、配列と関数はオブジェクトと参照型であるため、プロパティは変更されていないことがわかります。 o1 のプロパティとメソッドは o2 のプロパティとメソッドと同じ名前を持ちます。これらは参照ではなく、オブジェクトの定義されたプロパティとメソッドのコピーです。

これは属性の問題ではありませんが、メソッドにとっては大きな問題です。メソッドはまったく同じ機能を実行しますが、関数オブジェクトに数千のインスタンス メソッドがある場合、その各インスタンスにはコピーが 2 つ存在するためです。何千ものメソッドのコピーを維持しなければならないのですが、これは明らかに非科学的です。プロトタイプが誕生しました。

prototype

新しい関数が作成されるたびに、特定のルールに従ってその関数のプロトタイプ属性が作成されます。デフォルトでは、プロトタイプ属性はコンストラクター属性を取得します。この属性はポインターです。プロトタイプ属性が配置されている関数にコードを記述して、上の図を見てください。

コードは次のとおりです:


function Person(){
            }

JavaScriptでのプロトタイプの使い方を詳しく解説

上の図からわかるように、 person オブジェクトはプロトタイプ属性を自動的に取得します。プロトタイプもオブジェクトであり、コンストラクター属性を自動的に取得します。人物オブジェクトに。

インスタンスを作成するためにコンストラクターが呼び出されるとき、インスタンスにはコンストラクターのプロトタイプを指す内部ポインター (多くのブラウザーではこのポインターの名前は proto) が含まれます。この接続はインスタンスとインスタンスのプロトタイプの間に存在します。インスタンスとコンストラクターの間ではなく、コンストラクターの間です。

コードは次のとおりです:

function Person(name){
                this.name=name;
            }
            Person.prototype.printName=function(){
                alert(this.name);
            }
            var person1=new Person('Byron');
            var person2=new Person('Frank');

JavaScriptでのプロトタイプの使い方を詳しく解説

personインスタンスperson1にはname属性が含まれており、proto属性が自動的に生成されます。これは、personのプロトタイプを指し、おそらくプロトタイプで定義されているprintNameメソッドにアクセスできます。このように

JavaScriptでのプロトタイプの使い方を詳しく解説

写段程序测试一下看看prototype内属性、方法是能够共享

代码如下:

function Person(name){
                this.name=name;
            }
            Person.prototype.share=[];
            Person.prototype.printName=function(){
                alert(this.name);
            }
            var person1=new Person('Byron');
            var person2=new Person('Frank');
            person1.share.push(1);
            person2.share.push(2);
            console.log(person2.share); //[1,2]

果不其然!实际上当代码读取某个对象的某个属性的时候,都会执行一遍搜索,目标是具有给定名字的属性,搜索首先从对象实例开始,如果在实例中找到该属性则返回,如果没有则查找prototype,如果还是没有找到则继续递归prototype的prototype对象,直到找到为止,如果递归到object仍然没有则返回错误。同样道理如果在实例中定义如prototype同名的属性或函数,则会覆盖prototype的属性或函数。

代码如下:

function Person(name){                
this.name=name;            
}            
Person.prototype.share=[];
var person=new Person('Byron');            
person.share=0;            
console.log(person.share); //0而不是prototype中的[]

构造简单对象

当然prototype不是专门为解决上面问题而定义的,但是却解决了上面问题。了解了这些知识就可以构建一个科学些的、复用率高的对象,如果希望实例对象的属性或函数则定义到prototype中,如果希望每个实例单独拥有的属性或方法则定义到this中,可以通过构造函数传递实例化参数。

代码如下:

function Person(name){
                this.name=name;
            }
            Person.prototype.share=[];
            Person.prototype.printName=function(){
                alert(this.name);
            }

总结:

相信通过对本文的详细学习,很多小伙伴都知道JavaScript中prototype的使用有了进一步的了解,希望对你的工作有所帮助!

相关推荐:

JavaScript向对象添加属性和方法的属性prototype

Js如何使用prototype实现自定义数组的案例

JavaScript原型链prototype属性和方法实例详解

详细介绍javascript使用prototype实现OOP继承的方法

以上がJavaScriptでのプロトタイプの使い方を詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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