ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript オブジェクト指向プログラミング (オブジェクト作成)

JavaScript オブジェクト指向プログラミング (オブジェクト作成)

黄舟
黄舟オリジナル
2017-03-01 15:04:37983ブラウズ

まえがき

オブジェクト指向 (オブジェクト指向、oo) プログラミングを学ぶ前に、まずオブジェクトとは何かを知る必要があります。ECMA-262 ではオブジェクトを 」の集合として定義しています。そのプロパティには、基本的な値、オブジェクト、または関数を含めることができますJavaScript でオブジェクトを作成する方法はたくさんあります: ファクトリ パターン、コンストラクター パターン、プロトタイプ パターン、コンストラクター パターンとプロトタイプ パターンの組み合わせ、寄生コンストラクター パターンなど。

1. ファクトリ パターン

ファクトリ パターンは、ソフトウェア エンジニアリングの分野でよく知られている設計パターンであり、特定のオブジェクトを作成するプロセスを抽象化します。 ECMAScript ではクラスを作成できないことを考慮して、開発者は、特定のインターフェイスを使用してオブジェクト作成の詳細をカプセル化する関数を発明しました。

function createStudent(name, age, job){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
alert(this.name);
};
return o;
}
var student1= createStudent("xiaoming", 9, "student");
var student2 = createStudent("xiaowagn", 15, "student");

関数 createStudent() は、受け入れられたパラメーターに基づいて、必要なすべての情報を含む Student オブジェクトを構築できます。この関数は無制限に呼び出すことができ、毎回 3 つのプロパティと 1 つのメソッドを含むオブジェクトを返します。ファクトリ パターンは、複数の同様のオブジェクトを作成する問題を解決しますが、オブジェクト認識 (つまり、オブジェクトの種類を知る方法) の問題は解決しません。 JavaScript の発展により、別の新しいパターンが登場しました。 2. コンストラクターモード

まず、前のコードを次のように変更します:

function Student(name,age){
      this.name=name;
      this.age=age;
      this.showname=function(){
      alert(this.name);
      }
}
var xiaoming =new Student("xiaoming",6);
var xiaogang =new Student("xiaogang",7);

ファクトリーモードとの違い:

1.

作成されたオブジェクトは表示されません

2.

プロパティを

thisに直接割り当てますObject 3.

Returnステートメントはありません。 インスタンスを作成するには、

new

演算子を使用します。 オブジェクトを作成する手順:

1.

新しいオブジェクトを作成する

2.

コンストラクターのスコープを新しいオブジェクトに割り当てます(

thisはこの新しいオブジェクトを指します) 3 .

コンストラクターのコードを実行し、このオブジェクトに属性を追加します

4.

このオブジェクトを返す

 
alert(xiaoming.constructor==Student) //true;
オブジェクトの

constructor

属性は、元々はオブジェクトの型を識別するために使用されていました。オブジェクトの型を確認するか、instanceof

alert(xiaoming instanceof Student) //true
alert(xiaoming instanceof Object) //true是因为所有对象均继承自Object

を使用してください。カスタム コンストラクターを作成すると、将来的にはそのインスタンスを特定の型として識別できるようになり、ここでコンストラクター パターンがファクトリー パターンの場所に勝ります。コンストラクターの使用には欠点もあります。

つまり、各インスタンスで各メソッドを再作成する必要があります。

たとえば、、xiaoming、および xiaogang には両方とも showname() メソッドがあります。ただし、これら 2 つのメソッドは同じ Function のインスタンスではありません。 ECMAScript の関数はオブジェクトであるため、関数が定義されるたびにオブジェクトがインスタンス化されます。論理的な観点から見ると、現時点ではコンストラクターも次のように定義できます。

function student(name,age){
this.name=name;
this.showName=new Function(“alert(this.name)”);
}
ご覧のとおり、各

Student

インスタンスには、異なる Function インスタンスが含まれています。異なるインスタンス上の同じ名前の関数は同等ではありません。次のコードはこれを示しています。

alert(xiaoming.showName==xiaogang.showname);//false
2. コンストラクター パターン

作成するすべての関数にはプロトタイプ属性があり、この属性はオブジェクトを指すポインターであり、このオブジェクトの目的は、特定の型のすべてのインスタンスで共有できる情報を含めることです。プロパティとメソッド。文字通りに理解すると、プロトタイプは、コンストラクターを呼び出して作成されるオブジェクト インスタンスのプロトタイプ オブジェクトです。プロトタイプ オブジェクトを使用する利点は、すべてのオブジェクト インスタンスがそれに含まれるプロパティとメソッドを共有できることです。つまり、コンストラクターでオブジェクト インスタンスに関する情報を定義する代わりに、この情報をプロトタイプ オブジェクトに直接追加できます。

function Student(){
 
}
Student.property.name=”default name”;
Student.property.age=0;
Student.property.showName=funciton(){
alert(this.name);
}
Var xiaoming=new Student();
Var xiaogang=new Student();

与构造函数模式的不同时,新对象的这些属性和方法是由所有的实例共享的。换句话说xiaoming和xiaogang访问的都是同一组属性和同一个showName()函数。要理解原型模式的工作原理,必须先理解ECMAScript 中原型对象的性质。

1. 理解原型对象

无论什么时候,只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个prototype

属性,这个属性指向函数的原型对象。在默认情况下,所有原型对象都会自动获得一个constructor

(构造函数)属性,这个属性包含一个指向prototype 属性所在函数的指针。就拿前面的例子来说,

Student.prototype. constructor 指向Student。而通过这个构造函数,我们还可继续为原型对象添加其他属性和方法.

JS中我们通过isPropertyOf()来判断,某个实例是否指向某个函数的的原型。

Eg

Student.property.isPropertyOf(xiaoming);//true。

ECMAScript5中含增加了Object.getPropertyOf()方法来获取一个实例的原型

Eg

alert(Object.getPropertyOf(xiaoming)==Student.property);//true
alert(Object.getPropertyOf(xiaoming).name);//default name

此外,我们还可以通过hasOwnProperty()方法来检测一个属性是存在实例中还是存在原型中。alert(xiaoming.hasOwnProperty(“name”));//false

alert(xiaoming.property.hasOwnProperty(“name”));//true

原型模式也不是没有缺点。首先,它省略了为构造函数传递初始化参数这一环节,结果所有实例在默认情况下都将取得相同的属性值。虽然这会在某种程度上带来一些不方便,但还不是原型的最大问题。原型模式的最大问题是由其共享的本性所导致的。原型中所有属性是被很多实例共享的,这种共享对于函数非常合适。对于那些包含基本值的属性倒

也说得过去,毕竟(如前面的例子所示),通过在实例上添加一个同名属性,可以隐藏原型中的对应属性。然而,对于包含引用类型值的属性来说,问题就比较突出.

四、组合使用构造函数模式和原型模式

创建自定义类型的最常见方式,就是组合使用构造函数模式与原型模式。构造函数模式用于定义实例属性,而原型模式用于定义方法和共享的属性。结果,每个实例都会有自己的一份实例属性的副本,但同时又共享着对方法的引用,最大限度地节省了内存。另外,这种混成模式还支持向构造函数传递参数;可谓是集两种模式之长。

function Student(name,age){
this.name=name;
this.age=age;
}
Student.property.showName=funciton(){alert(this.name);}

这种构造函数与原型混成的模式,是目前在ECMAScript 中使用最广泛、认同度最高的一种创建自定义类型的方法。可以说,这是用来定义引用类型的一种默认模式。

五、寄生构造函数模式

通常,在前述的几种模式都不适用的情况下,可以使用寄生(parasitic)构造函数模式。这种模式的基本思想是创建一个函数,该函数的作用仅仅是封装创建对象的代码,然后再返回新创建的对象;但从表面上看,这个函数又很像是典型的构造函数。

funciton Student(name,age){
Var o=new Object();
o.name=name;
o.age=age;
o.showName=function(){alert(this.name);}
Reurn o;
}

关于寄生构造函数模式,有一点需要说明:首先,返回的对象与构造函数或者与构造函数的原型属性之间没有关系;也就是说,构造函数返回的对象与在构造函数外部创建的对象没有什么不同。为此,不能依赖instanceof 操作符来确定对象类型。由于存在上述问题,我们建议在可以使用其他模式的情况下,不要使用这种模式。个人感觉这模式还是有点模仿工厂模式。

 以上就是JavaScript面向对象编程(对象创建)的内容,更多相关内容请关注PHP中文网(www.php.cn)!


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