Javascriptオブジェクトの字面量と構造関数

6339 ワード

オブジェクトの作成方法
オブジェクトの字面量:カッコ内のカンマで分割されたキー値(key-value)ペアをパッケージ化してオブジェクトを作成する優美なオブジェクト作成方法です.コンストラクション関数:主に組み込みコンストラクション関数(ほとんど常により短く字面量表現)とカスタムコンストラクション関数が含まれます.
example.
//     
var car = {goes: 'far'};
//        (   )
var car = new Object();
car.goes = 'far';

フォント量モードを優先的に選択してオブジェクトを作成するもう1つの理由は、オブジェクトから抽出された属性やメソッドではなく、オブジェクトが可変ハッシュマッピングであることを強調するためです.Objectコンストラクション関数を使用するのに対して,字面量を使用するもう一つの理由は,ドメイン解析が機能していないためである.ローカルコンストラクション関数が同じ名前で作成される可能性があるため、解釈器は、グローバルObjectコンストラクション関数が発見されるまで、Object()を呼び出す場所から役割ドメインチェーンを上向きにクエリーする必要があります.
Object()コンストラクション関数は、1つのパラメータのみを受け入れ、伝達された値にも依存します.このObject()は、オブジェクトを作成するために別の組み込みコンストラクション関数を委任し、望ましくない異なるオブジェクトを返す可能性があります.Object()コンストラクション関数に渡される値が動的であり、実行時にそのタイプが決定されるまで、Object()コンストラクション関数のこのような動作は、予想外の結果をもたらす可能性があります.したがってnew Object()コンストラクション関数を使用するのではなく、より単純で信頼性の高いオブジェクト字面量モードを使用する必要があります.
カスタムコンストラクタ
var Person = function(name){
    this.name = name;
    this.say = function(){
    return 'I am ' + this.name;
    };
};

newオペレータでコンストラクション関数を呼び出すと、関数内部で次のような状況が発生します.空のオブジェクトを作成し、this変数はオブジェクトを参照し、関数のプロトタイプも継承します.2.属性とメソッドがthis参照のオブジェクトに追加されます.3.新しく作成されたオブジェクトはthisによって参照され、最後にthisが明示的に返されない場合は、thisが暗黙的に返されます.
以上の状況は、バックグラウンドで次のようなことが起こったように見えます.
var Person = function(name){
    //              
    //var this = {};
    // this       
    this.name = name;
    this.say = function(){
        return 'I am ' + this.name;
    };
    //return this;
};

この例では、say()メソッドをthisに追加します.これにより、new Person()が呼び出されるたびにメモリに新しい関数が作成されます.この方法は,複数のインスタンス間のsay()法が実際には変化していないため,明らかに非効率である.より良い選択は、Personクラスのプロトタイプにメソッドを追加することです.再利用可能なメンバー(再利用可能なメソッドなど)は、オブジェクトのプロトタイプに配置する必要があります.
この例では、var this = {};は真実のすべてではありません.「空」オブジェクトは実際には空ではないため、Personのプロトタイプから多くのメンバーを継承しています.したがって、次の文のようになります.
var this = Object.create(Person.prototype);

コンストラクション関数は、return文を明示的に追加することなく、thisを暗黙的に返します.ただし、必要に応じて他のオブジェクトを返すことができます.
強制newのモード
コンストラクション関数を呼び出すときにnewオペレータを使用するのを忘れた場合、コンストラクション関数のthisはグローバルオブジェクトを指します(ブラウザではwindowを指します).
example.
function Waffle(){
    this.tastes = 'yummy';
}
//   :    new   
var mm = Waffle();
console.log(typeof mm);  //output: undefined
console.log(window.tastes);  //output: yummy

上記のような予期せぬ動作はECMAScript 5で解決され、strictモードではグローバルオブジェクトを指すことはありません.
シナリオ1:thatの使用
function Waffle(){
    var that = {};
    that.tastes = 'yummy';
    return that;
}

このモードの問題は、プロトタイプへのリンクが失われるため、Waffle()プロトタイプに追加されたメンバーは、オブジェクトには使用できません.
シナリオ2:自己呼び出しコンストラクタ
コンストラクション関数でthisがコンストラクション関数のインスタンスであるかどうかを確認できます.そうでない場合、コンストラクション関数は自身を再度呼び出し、今回の呼び出しでnewオペレータを正しく使用できます.
example.
function Waffle(){
    if(!(this instanceof Waffle)){
        return new Waffle();
    }
    this.tastes = 'yummy';
}
Waffle.prototype.wantAnother = true;

var first = new Waffle();
var second = Waffle();
console.log(first.tastes);  //output: yummy
console.log(second.tastes);  //output: yummy
console.log(first.wantAnother);  //output: true
console.log(second.wantAnother);  //output: true

インスタンスオブジェクトを検出するための別の一般的な方法は、コード内で構造関数名をハードコーディングするのではなく、arguments.calleeと比較することである.
if(!(this instanceof arguments.callee)){
    return new arguments.callee();
}

注意:ES 5のstrictモードではargumentsはサポートされていません.calleeプロパティ.
転載先http://ju.outofmemory.cn/entry/157897