JavaScriptオブジェクト向け(1)

6151 ワード

以下のJSはECMA-262第5版
オブジェクト向けとは
オブジェクト向けはプロセス向けとは異なる考え方です.類を型にしてケーキを作る.しかしJSにはクラスがなく、そのオブジェクトは他のクラスベースの言語のオブジェクトとは異なる.Javaのオブジェクト:3つの主な特徴、動作・状態・フラグがあります.すなわち、現在の特徴を記述する情報、一意のアイデンティティを保存する独自の呼び出し可能な方法である.Pythonのオブジェクト:特性とメソッドを含む集合;JSのオブジェクト:基本値、オブジェクト、または関数を含む無秩序属性の集合.(ECMA-262)実際にはハッシュリストである.
JSのオブジェクトが典型的なオブジェクト向け言語と異なる以上、なぜJSはオブジェクト向けにできるのか.
回答が必要な質問:
  • JSの対象はどうなっていますか?
  • オブジェクト向けのニーズは何ですか?
  • JSのオブジェクトはオブジェクト向けのニーズに合っていますか?どうすれば合いますか?
  • JSの【引用タイプ】と【クラス】の違い
  • 1.JSの相手はどんな人ですか.
  • JSのオブジェクトは無秩序属性の集合であり、その属性は基本値、オブジェクトまたは関数を含むことができる.(ECMA-262)実際にはハッシュリストである;
  • JSのオブジェクトは、Objectのインスタンス(参照タイプのインスタンス)であり、参照タイプの値とも呼ばれます.各インスタンスには、constructor、hasOwnProperty()、isPrototypeOf()、propertyIsEnumerable()、toLocaleString()、toString()、valueOf()の7つのプロパティ/メソッドがあります.
  • JSのオブジェクトには、データ属性とアクセサ属性の2つの属性があります.データ属性には、[[Configurable],[[Enumberable],[[Writable],[[Value]]があります.アクセサのプロパティには、次の4つのプロパティ[[Configurabel]],[[Enumberable],[[Get]],[[Set]]を持つgetter、setter関数のペアがあります.この2つの属性はいずれもObjectを用いる.defineProperty()を変更します.
  •  //ECMAScript 5 Object.defineProperty() method (IE9 and Firefox 4).
            var book = {
                _year: 2004,
                name: "javascript",
                edition: 1
            };
            //       
            Object.defineProperty(book, "name" , {
                configurable : false,
                value : "python"
            })
    
            //        
            Object.defineProperty(book, "year", {
                get: function(){
                    return this._year;
                },
                set: function(newValue){
                
                    if (newValue > 2004) {
                        this._year = newValue;
                        this.edition += newValue - 2004;
                    
                    }
                }
            });
            
            alert(book.name) //python
            delete book.name  //        configurable   false ,      
            alert(book.name) //python
    
            book.year = 2005;
            alert(book.edition);   //2
    
    

    2.オブジェクト向けのニーズは何ですか?
    パッケージ、継承、マルチステートパッケージは、実装の詳細を非表示にし、コードをモジュール化することができる.継承は既存のコードモジュール(クラス)を拡張できます.それらの目的はすべてコードの再利用です.マルチステートは別の目的を実現するためです.インタフェースの再利用です.クリックして抜粋してください.
    3.JSは対象に対する要求を満たすことができますか?
  • JSはパッケージを実現できますか?この問題はJSに進化して詳細を隠すことができて、コードをモジュール化することができますか?既知のパターンは以下の通りである:ファクトリパターン、コンストラクション関数パターン、プロトタイプパターン、ES 6のClassファクトリパターン:類似オブジェクトの問題を解決したが、オブジェクト識別の問題を解決せず、オブジェクトのタイプを知らない.コンストラクション関数モード:
  •         function Person(name, age, job){
                this.name = name;
                this.age = age;
                this.job = job;
                this.sayName = function(){
                    alert(this.name);
                };    
            }
            
            var person1 = new Person("Nicholas", 29, "Software Engineer");
            var person2 = new Person("Greg", 27, "Doctor");
            
            person1.sayName();   //"Nicholas"
            person2.sayName();   //"Greg"
            
            alert(person1 instanceof Object);  //true
            alert(person1 instanceof Person);  //true
            alert(person2 instanceof Object);  //true
            alert(person2 instanceof Person);  //true
            
            alert(person1.constructor == Person);  //true
            alert(person2.constructor == Person);  //true      
    
          //     constructor, instanceof              
    
          //                
            alert(person1.sayName == person2.sayName); //false
          //                   
            function Person(name, age, job){
                this.name = name;
                this.age = age;
                this.job = job;
                this.sayName = sayName;
            }
            
            function sayName(){
                alert(this.name);
            }
    

    コンストラクション関数は実際に経験しました:オブジェクトの作成===プロトタイプ:
            function Person(){
            }
            
            Person.prototype.name = "Nicholas";
            Person.prototype.age = 29;
            Person.prototype.job = "Software Engineer";
            Person.prototype.sayName = function(){
                alert(this.name);
            };
            
            var person1 = new Person();
            person1.sayName();   //"Nicholas"
            
            var person2 = new Person();
            person2.sayName();   //"Nicholas"
          
            alert(person1.sayName == person2.sayName);  //true
            
            alert(Person.prototype.isPrototypeOf(person1));  //true
            alert(Person.prototype.isPrototypeOf(person2));  //true
            
            //only works if Object.getPrototypeOf() is available
            if (Object.getPrototypeOf){
                alert(Object.getPrototypeOf(person1) == Person.prototype);  //true
                alert(Object.getPrototypeOf(person1).name);  //"Nicholas"
            }
    

    ES 6 classモード:
    class Point{
      constructor(x,y){
            this.x = x
            this.y = y
        }
        toString(){
            return "(" + this.x + "," + this.y +")"
        }
    }
    
    

    ES 6の構文は実際には構文糖であり、上記のパターンは関数パターンとプロトタイプパターンを組み合わせて使用することに相当する.
    function Point(x,y){
        this.x = x
        this.y = y
    }
    Point.prototype.toString = function(){
        return "(" + this.x + "," + this.y +")"
    }
    

    ダイナミックプロトタイプモード:メソッドが存在しない場合にのみメソッドを追加します.
          function Person(name, age, job){
          
              //properties
              this.name = name;
              this.age = age;
              this.job = job;
              
              //methods
              if (typeof this.sayName != "function"){
              
                  Person.prototype.sayName = function(){
                      alert(this.name);
                  };
                  
              }
          }
    
          var friend = new Person("Nicholas", 29, "Software Engineer");
          friend.sayName();
    
    
  • JSはどのように継承しますか?JSの関数は署名されていないので,インタフェース継承はサポートされず,実装継承のみがサポートされ,プロトタイプチェーンによって実現される.各関数にはプロトタイプオブジェクトprototypeがあり、プロトタイプオブジェクトのconstructorプロパティはprotoypeプロパティが存在する関数を指すポインタです.オブジェクトのプロパティを読み込むと、オブジェクト自体から1レベル1レベル上に検索されます.インスタンスに指定した名前のプロパティが見つかった場合は、そのプロパティの値を返し、見つからなかった場合は、ポインタが指すプロトタイプオブジェクトの検索を続行します.

  • いくつかの継承方式について、次の編で