有關javaScript面向對象和原型筆記

javaScript是一種比較特殊的語言,ECMAScript中沒有類的概念,跟其他面向對象的語言有一定的區別,它的對象也與基於類的語言中的對象有所不同,嚴格來說,javascript對象是一組沒有特定順序的值,對象的每個屬性或方法都有一個名字,而每個名字都映射到一個值。每個對象都是基於一個引用類型的創建的。

創建自定義對象的最簡單的方式就是創建一個Object的實例,然後再為其添加屬性和方法,如:

var box = new Object();        //創建對象
box.name1 = 'Lee';                    //添加屬性
box.age = 100;                        //
box.run = function () {
    return this.name1 + this.age       //this表示當前作用域下對象

不足:使用同一個接口創建很多對象,會產生很多重復代碼。

工廠模式:

在ECMAScript中無法創建類,開發人員就想出瞭另外一種方法,用一種函數來封裝以特定接口創建對象的細節,如:

   function createPerson(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 person1 = createPerson('lilei',29,'Software Engineer');
    var person2 = createPerson('Greg',27,'Doctor');
    person1.sayName();
    person2.sayName();
    alert(typeof person1);
    alert(typeof person2);


函數creatPerson()能夠根據接受的參數來構建一個包含所有必要信息的Person對象,可以無數次低調用這個函數,而每次它都返回一個包含三個屬性的一個方法的對象。工廠模式雖然解決瞭創建多個類型對象的問題,但卻沒有解決對象識別的問題。

構造函數模式

function Person(name,age,job){
        this.name = name;
        this.age = age;
        this.job = job;
        this.sayName = function(){
            alert(this.name);
        };
    }
    var person1 = new Person('lilei',29,'Software Engineer');
    var person2 =new Person('Greg',27,'Doctor');
    person1.sayName();
    person2.sayName();
    alert( person1 instanceof Object); 
    alert( person2 instanceof Person);



在這個例子當中,Person()函數取代瞭createPerson()函數。同時註意到跟createPerson()函數的區別:

沒有顯式地創建對象;

直接將屬性和方法賦給瞭this對象;

沒有return 語句;

構成方法首個字母大寫;

構造函數的的問題也有,就是每個方法都要在每個實例上重新創建一遍,

組合使用構造函數模式和原型模式

創建自定義類型常見的方式是組合使用構造函數模式和原型模式。構造函數模式用於定義實例屬性,而原型模式用定義方法和共享屬性,從而每個實例都會有 自己的一份實例屬性的副本,但同時又共享著對方的方法的引用,

function Person(name,age,job){
    this.name =name;
    this.age = age;
    this.friends = ["Shelpy","Court"];
    }
    Person.prototype = {
    constructor:Person,
    sayName:function(){
    alert(this.name)
    }
    }
    var person1 = new Person('lilei',29,'Software Engineer');
    var person2 = new Person('Greg',27,'Doctor');
    person1.friends.push("Van");
    alert(person1.friends);
    alert(person2.friends);
    alert(person1.friends === person2.friends);
    alert(person1.sayName === person2.sayName);

在這個例子中,實例屬性都是在構造函數中定義的,而由所有實例共享的屬性consructor和方法sayName()則是在原型中定義的,當修改瞭person1.friends時,並不會影響到person2,.friends,因為它們引用瞭不同的數組。

發佈留言