Javascript學習之建立對象

在Javascript中,除了幾種原始類型外,其他皆爲對象(Object,Array ...),既然對象如此重要,那就列舉一下在Javascript中如何建立對象:javascript

經過Object構造函數建立對象實例
var person = new Object();
person.name = 'krew';
person.age = 26;
對象字面量

對象字面量是對象定義的一種簡寫形式,目的在於簡化建立包含大量屬性的對象的過程。java

var person = {
  name : 'krew',
  age : 26
}
工廠模式

工廠模式是一種設計模式,經過對建立具體對象的過程進行抽象。使用函數來封裝建立對象的細節,能夠無數次地調用用該函數,每次均可以獲得包含制定內容的對象。設計模式

function personFactory(name, age){
  var obj = new Object();
  obj.name = name;
  obj.age = age;
  obj.sayName = function(){
    console.log(this.name);
  }
  return obj;
}

var person1 = personFactory('krew', 26);  
var person2 = personFactory('john', 20);
構造函數模式

基於工廠模式建立對象雖然方便,可是建立出來的對象沒有特定的對象類型(好比原生對象Object, Array的實例都有本身的類型),因此就採用構造函數模式來建立對象,就能解決識別對象類型的問題。數組

function Person(name, age){
  this.name = name;
  this.age = age;
  this.sayName = function() {
    console.log(this.name);
  }
}

var person1 = new Person('krew', 26);
var person2 = new Person('john', 20);

person1.sayName();  // 'krew'
person2.sayName();  // 'john'

person1.constructor == Person  // true
person2.constructor == Person  // true
原型模式

每一個函數在建立的時候,就會根據特定的規則爲該函數建立一個prototype屬性,這個屬性是指向函數的原型對象的指針。這個原型對象的包含能夠由特定類型的全部實例共享的屬性和方法。因此,在構造函數的prototype屬性上添加屬性與方法,該構造函數的全部實例都會在原型鏈上查找到這些屬性與方法。函數

function Person() {
}
Person.prototype.name = 'krew';
Person.prototype.age = 26;
Person.prototype.sayName = function() {
  console.log(this.name);
}

var person1 = new Person();
var person2 = new Person();

person1.sayName();  // 'krew'
person2.sayName();  // 'krew'
組合構造函數和原型模式

因爲原型對象中的屬性是被不少實例所共享的,對於引用類型的屬性值,將會存在實例間沒法隔離的問題:this

function Person() {
}
Person.prototype = {
  constructor : Person,
  name : 'krew',
  age : 26,
  friends : ['john', 'kitty'],
  showFriends : function() {
    console.log(this.friends);
  }
}
var person1 = new Person();
var person2 = new Person();

person1.friends.push('petter');

person1.showFriends()  // ['john', 'kitty', 'petter']
person2.showFriends()  // ['john', 'kitty', 'petter']

能夠看到,僅是在實例person1的friends屬性上添加值,但person2也跟着變化。這是由於friends數組存在於Person.prototype而非person1中,person1與person2中的friends皆爲引用Person.prototype中的friends,因此當經過person1來改變friends的時候,person2中的friends也會反映出來。
經過組合構造函數與原型模式能夠解決上面出現的問題,構造函數模式用於定義實例屬性,而原型模式用於定義方法和共享的屬性,每一個實例會有本身的一份實例屬性,同時又共享着方法的引用,極大的節省了內存。prototype

function Person(name, age) {
  this.name = name;
  this.age = age;
}

Person.prototype.sayName = function() {
  console.log(this.name);
}

var person1 = new Person('krew', 26);
var person2 = new Person('john', 20);

person1.sayName();  // 'krew'
person2.sayName();  // 'john'
動態原型模式
function Person(name, age){
  this.name = name;
  this.age = age;
  if (typeof this.sayName != 'function') {
    Person.prototype.sayName = function() {
      console.log(this.name);
    }
  }
}

var person1 = new Person('krew', 26);
var person2 = new Person('john', 20);

person1.sayName();  // 'krew'
person2.sayName();  // 'john'
寄生構造函數模式
function Person(name, age) {
  var obj = new Object();
  obj.name = name;
  obj.age = age;
  obj.sayName = function() {
    console.log(this.name);
  }
  return obj;
}

var person1 = new Person('krew', 26);
var person2 = new Person('john', 20);

person1.sayName();  // 'krew'
person2.sayName();  // 'john'
穩妥構造函數模式
function Person(name) {
  var obj = new Object();
  obj.sayName = function() {
    console.log(name);
  }
  return obj;
}

var person1 = Person('krew');
var person2 = Person('john');

person1.sayName();  // 'krew'
person2.sayName();  // 'john'
相關文章
相關標籤/搜索