一般的に使用されるいくつかのオブジェクト作成モード
新しいキーワードを使用して作成
オブジェクト作成の最も基本的な方法は、他のほとんどの言語とまったく同じです。オブジェクトは存在しないので、新しいオブジェクトを作成します。
var gf = new Object(); gf.name = "tangwei"; gf.bar = "c++"; gf.sayWhat = function() { console.log(this.name + "said:love you forever"); }
リテラルを使用して作成
これは適切だと思われますが、オタクは変数を定義するこのような複雑で控えめな方法を好むのでしょうか? スクリプト言語としては、他の言語と同じスタイルを持つ必要があるため、オブジェクト リテラルの定義方法が表示されました。 🎜>
var gf = { name : "tangwei", bar : "c++", sayWhat : function() { console.log(this.name + "said:love you forever"); } }
工場出荷時モード
function createGf(name, bar) { var o = new Object(); o.name = name; o.bar = bar; o.sayWhat = function() { alert(this.name + "said:love you forever"); } return o; } var gf1 = createGf("bingbing","d"); var gf2 = createGf("mimi","a");
コンストラクター
function Gf(name,bar){ this.name = name; this.bar = bar; this.sayWhat = function(){ alert(this.name + "said:love you forever"); } } var gf1 = new Gf("vivian","f"); var gf2 = new Gf("vivian2","f");
上記のメソッドには何も問題がないように見えますが、2 つのインスタンスで呼び出されるコンストラクター内の SayWhat メソッドが同じ Function インスタンスではないことがわかります:
console.log(gf1.sayWhat == gf2.sayWhat); //false
function Gf(name,bar){ this.name = name; this.bar = bar; this.sayWhat = sayWhat } function sayWhat(){ alert(this.name + "said:love you forever"); }
プロトタイプオブジェクトパターン
プロトタイプ オブジェクトを理解する
関数を作成すると、その関数には、コンストラクターを通じて作成された関数のプロトタイプ オブジェクトを指すプロトタイプ属性が含まれます。平たく言えば、プロトタイプ オブジェクトは、他のオブジェクトに共有プロパティとメソッドを提供するメモリ内のオブジェクトです。
プロトタイプ モードでは、コンストラクターでインスタンス属性を定義する必要はなく、属性情報をプロトタイプ オブジェクトに直接割り当てることができます。
function Gf(){ Gf.prototype.name = "vivian"; Gf.prototype.bar = "c++"; Gf.prototype.sayWhat = function(){ alert(this.name + "said:love you forever"); } } var gf1 = new Gf(); gf1.sayWhat(); var gf2 = new Gf();
すべてのオブジェクトにはプロトタイプ オブジェクト (プロトタイプ) があります。プロトタイプ オブジェクトには、プロトタイプ属性を含む関数を指すコンストラクター属性があります。Gf インスタンス gf1 と gf2 には両方とも、プロトタイプ オブジェクトを指す内部属性が含まれています (Firefox ブラウザーで表示)。はプライベート プロパティ プロトです)、オブジェクト内のプロパティにアクセスするときは、まずそのプロパティがインスタンス オブジェクトに存在するかどうかを尋ね、存在しない場合はプロトタイプ オブジェクトを探し続けます。
プロトタイプ オブジェクトを使用する
前の例では、プロトタイプ オブジェクトに属性を追加するときに、各オブジェクトに Gf.prototype を追加する必要があることがわかりました。上記のオブジェクト作成モードでは、リテラルを使用できることがわかりました。オブジェクトを作成します。ここで改善することもできます:
function Gf(){} Gf.prototype = { name : "vivian", bar : "c++", sayWhat : function(){ alert(this.name + "said:love you forever"); } }
を指します。
var gf1 = new Gf(); console.log(gf1.constructor == Gf);//false console.log(gf1.constructor == Object)//true
一般情况下,这个微妙的改变是不会对我们造成影响的,但如果你对constructor有特殊的需求,我们也可以显式的指定下Gf.prototype的constructor属性:
Gf.prototype = { constructor : Gf, name : "vivian", bar : "c++", sayWhat : function() { alert(this.name + "said:love you forever"); } } var gf1 = new Gf(); console.log(gf1.constructor == Gf);//true
通过对原型对象模式的初步了解,我们发现所有的实例对象都共享相同的属性,这是原型模式的基本特点,但往往对于开发者来说这是把“双刃剑”,在实际开发中,我们希望的实例应该是具备自己的属性,这也是在实际开发中很少有人单独使用原型模式的主要原因。
构造函数和原型组合模式
在实际开发中,我们可以使用构造函数来定义对象的属性,使用原型来定义共享的属性和方法,这样我们就可以传递不同的参数来创建出不同的对象,同时又拥有了共享的方法和属性。
function Gf(name,bar){ this.name = name; this.bar = bar; } Gf.prototype = { constructor : Gf, sayWhat : function() { alert(this.name + "said:love you forever"); } } var gf1 = new Gf("vivian", "f"); var gf2 = new Gf("vivian1", "c");
在这个例子中,我们再构造函数中定义了对象各自的属性值,在原型对象中定义了constructor属性和sayWhat函数,这样gf1和gf2属性之间就不会产生影响了。这种模式也是实际开发中最常用的对象定义方式,包括很多js库(bootstrap等)默认的采用的模式。