1. 程式人生 > >ECMAScript面向對象(二)——之創建對象方法總結

ECMAScript面向對象(二)——之創建對象方法總結

擴展 console 動態 原型 struct 私有屬性 true asc 一份

創建對象的方法

  1. 工廠模式

缺點:無法識別對象的類型,因為根本沒有定義新的對象類型

// 工廠模式創建對象
  //定義
function createPerson(name,age,job){
    var o=new Object();
    o.name=name;
    o.age=age;
    o.job=job;
    o.sayHi=function(){console.log(‘Hi!‘)};

    return o;
}
//使用
 var p1=createPerson("JayChou","28","歌手");

  2.構造函數模式

缺點:創建對象實例的時候其實每個屬性和方法都要重新創建一份。造成即使是同一個對象創建的實例,但是它們相同的方法並非相等。

因為作用域鏈和標識符解析不同。

// 構造函數模式
  //定義
function Person(name,age,job){
    this.name=name;
    this.age=age;
    this.job=job;
    this.sayHi=function(){console.log(‘Hi!‘)};
}
 //使用
  var p11=new Person("JayChou","28","歌手");
  var p12=new Person("JayChou","29","歌手");
   
   console.log(p11.sayHi==p12.sayHi);//false

  3.原型模式

利用函數的原型指針屬性:prototype 指向一個對象。這個對象是由特定類型的所有實例共享的屬性和方法。
缺點:如果屬性中有引用類型,那麽在任何一個實例中,對引用類型的屬性進行操作會影響到所有的實例該引用類型。
// 原型模式
function Person(){}
  
 Person.prototype={
   constructoe:Person,
   name:"koo",
   sex:"man",
   arr:[1,2,3],//引用類型的值,通過引用訪問
   sayHi:function(){
       console.log("Hi!");
   }
 };
  
var obj=new Person(); var obj1=new Person(); obj1.name="sss"; obj1.arr.push(5); console.log(obj.name);// koo console.log(obj1.name);// sss console.log(obj.arr);//1,2,3,5 console.log(obj1.arr);//1,2,3,5

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

綜合構造函數和原型的特性,使用構造函數定義實例特有屬性和方法,原型則定義共享屬性和方法

// 構造原型組合模式
function Person(name,age,job){
    this.name=name; //實例特有屬性寫在構造函數中
    this.age=age;
    this.job=job;
    this.arr=[1,2,3];
}

// 實例公共屬性和方法寫在原型中
Person.prototype.sayHi=function(){console.log(‘say Hi!‘)};

//使用
var person1=new Person("Jay",28,"歌手");
person1.arr.push(20);
console.log(person1.arr);//[1,2,3,20]
var person2=new Person("coco",30,"歌手");
person2.arr.push(10);
console.log(person2.arr);//[1,2,3,10]

  5.動態原型模式

和上面的組合模式相似,只是將原型公共屬性的定義寫在構造函數的內部。

// 動態原型模式
function Person(name,age,job){
    this.name=name; //實例特有屬性寫在構造函數中
    this.age=age;
    this.job=job;
    this.arr=[1,2,3];

  if (typeof this.sayHi !="function") {
      // 實例公共屬性和方法寫在原型中,但是這裏不能用字面量的形式定義
    Person.prototype.sayHi=function(){console.log(‘say Hi!‘)};
  }
}

  6.寄生構造模式——一般用於擴展原生引用類型

這個模式和工程模式類似,只是在創建對象的時候,寄生模式還是使用new關鍵字方式。返回的對象不是new關鍵字生成的,而是通過return返回的,它覆蓋了new生成的對象。
返回的對象與構造函數、構造函數的原型對象直接沒有關系。
// 寄生構造函數模式 
//
function MyArray(){
   var o=new Array();
    o.toPipedString=function(){
        return this.join("|");
    };
    return o;
}

var arr=new MyArray();

console.log(arr instanceof MyArray);//false
console.log(arr instanceof Array);//true
console.log(arr instanceof Object);//true

  7.穩妥構造函數模式

這裏類說說這個穩妥對象的概念。穩妥對象,指的是沒有公共屬性,而且其方法也不引用this的對象。適合在那些禁止用new和this的場景中使用。

// 穩妥構造函數模式
function Person(name,age,job){
    var o=new Object();

    //私有屬性
    name=name; 
    age=age;
    job=job;

    // 對外接口,只有這個接口可以訪問內部屬性
   o.sayHi=function(){
    console.log(‘hi,‘+name);
  };
  return o;
}
var p1=Person("JayChou","29","歌手");
p1.sayHi();//hi,JayChou
console.log(p1.name);//undefined 無法訪問內部屬性

ECMAScript面向對象(二)——之創建對象方法總結