天天看點

建立對象的幾種模式

/**
*下面是一些建立對象的模式,可反複看
*以建立人為例子,人有自己的名字和年齡,并有一個說自己名字和年齡的方法
**/

//模式一:為了避免重複代碼如var obj = {....}的代碼出現,萌生了最初的工廠模式,缺點:無法獲知對象的類型
function createPerson(name,age){
    // 建立一個對象
    var o = new Object();
    o.name = name;
    o.age = age;
    o.say = function(){
        console.log('My name is ' + this.name + "; my age is " +  this.age + '.');
    }
    //工廠模式傳回封裝好的對象
    return o;
}
var sqf = createPerson('shaoqianfei',);
sqf.say();
console.log(sqf instanceof Object);
// 這是缺陷所在,無法獲知類型
console.log(sqf instanceof createPerson);

//模式二:構造函數模式,用的比較多的,this和new Person()是關鍵,注意,還沒有return.
// 構造函數,相當于java中的類
function Person(name,age){
    // 關鍵要弄清楚new之後此函數内發生了什麼
    this.name = name;
    this.age = age;
    this.say = function(){
        console.log('My name is ' + this.name + "; my age is " +  this.age + '.');
    };
}
var person1 = new Person('liuxiang',);
var person2 = new Person('liuxiang2',);
person1.say();
console.log(person1 instanceof Object);
// 這是相比工廠模式的其中一個優點,可以獲知類型
console.log(person1 instanceof Person);
// 缺點,每次new一個對象,就要在Person()裡面重新執行一遍say(),因為person1和person2的say()不相同,而函數也是對象,不信看下面
console.log(person1.say == person2.say); //false 
//是以,這種方式(構造函數方式)在完成同樣任務時,卻要産生多個say()執行個體,沒有必要這樣,沒必要在之前就将函數綁定到特定對象
//可以采取将函數對象建立到構造函數外面,用變量引用的方法(指針)來達到隻需要建立一次方法就ok的目的。見高程第三版p147第5行的函數。

//但是呢。由于構造函數的這個缺點,我們又不能完全把函數定義到全局,因為,如果對象的方法很多,那麼全局方法也就很多。而且,沒有封裝好
//是以,我們用原型模式可以實作。
//模式三: 原型模式
console.log("模式三:原型模式,我們先看看之前的原型是怎樣的");
console.log(Person.prototype.isPrototypeOf(person1));  //Person.proto對象是person1的原型嗎?回答: 是的
console.log(Object.getPrototypeOf(person1) == Person.prototype);  //(ie9+方法)person1的原型對象是不是與Person.prototype指向的對象相等? 是的