1. 程式人生 > 程式設計 >js 建立物件的多種方式與優缺點小結

js 建立物件的多種方式與優缺點小結

早期建立方式

var obj = new Object()
obj.name ='xxx'
obj.age = 18
或使用物件字面量
var o1 = {
  name: 'xxx',say: () => {}
}
var o2 = {
  name: 'xxx',say: () => {}
}

缺點:使用同一個介面建立很多物件,會產生大量重複程式碼

工廠模式

function factory(name,age) {
  var obj = new Object()
  obj.name = name
  obj.age = age
  return obj
}
var o1 = factory(1,11)
var o2 = factory(2,22)

優點:解決了建立多個相似物件程式碼重複問題
缺點:無法識別物件是什麼型別

建構函式模式

ECMAScript中可以使用建構函式建立特定型別的物件,如Object,Array這種原生建構函式。此外,也可以建立自定義建構函式,從而定義自定義物件的屬性和方法。

function Person(name,age) {
  this.name = name
  this.age = age
  this.sayName = function() {
    console.log(this.name)
  }
}
var o1 = new Person(1,11)
var o2 = new Person(2,22)
o1.sayName() // 1
o2.sayName() // 2

優點:建構函式模式建立的例項可以區分型別標識(instanceof 判斷)
缺點:每個方法都需要在例項上重新建立,如 兩個例項的sayName方法任務相同,但是實際建立了兩個Function例項

建構函式模式優化

function Person(name,age) {
  this.name = name
  this.age = age
}
function sayName () {
  console.程式設計客棧log(this.name)
}
var o1 = new Person(1,22)
o1.sayName() // 1
o2.sayName() // 2

優點:多個例項共享在全域性作用域中定義的函式,解決了兩個函式做同一件事的問題

缺點:全域性作用域定義的函式實際上只能被某個物件呼叫,全域性作用域名不副實,而且如果物件需要定義很多方法,需要建立很多個全域性函式,這讓自定義的物件型別沒有封裝特性。

原型模式

我們建立的每個函式都有一個protoype屬性,這個屬性是一個指標,指向一個物件。這個物件的用途是包含了可以由特定型別的所有例項共享的屬性和方法。即prototype就是由建構函式建立的那個物件例項的原型物件。

function Person(){}
Person.protot程式設計客棧ype.name = '123'
Person.prototype.age = 18
Person.prototype.sayName = function() {
  console.log(this.name)
}
var o1 = new Person(1,22)
o1.sayName() // 123
o2.sayName() // 123

優點:解決了例項共享屬性或事件的問題
缺點:因為例項共享屬性的原因,對於值為引用型別的屬性來說,一個例項的修改會導致其他例項訪問gLQfoHsJA值更改。如:

function Person(){}
Person.prototype.name = '123'
Person.prototype.age = 18
Person.prototype.friends = ['a','b']
Person.prototype.sayName = function() {
  console.log(this.nagLQfoHsJAme)
}
var o1 = new Person(1,22)
o1.friends.push('c')
console.log(o2.friends) // ['a','b','c']

建構函式和原型模式組合

function Person(name,age) {
  this.name = name
  this.age = age
  this.friends = ['a']
}
Person.prototype = {
  constructor: Person,sayName: function() {
    console.log(this.name)
  }
}
var o1 = new Person(1,22)
o1.sayName() // 1
o2.sayName() // 2

優點:每個例項有自己的屬性,同時又共享著方法的引用,還支援傳引數

動態原型模式

function Person(name,age) {
  this.name = name
  this.age = age
  this.friends = ['a']
  if(typeof this.sayName != 'function') {
    Person.prototype.sayName = function() {
      console.log(this.name)
    }
  }
}
var o1 = new Person(1,22)
o1.sayName() // 1
o2.sayName() // 2

優點:僅在方法不存在的時候建立一次,避免重複建立

寄生建構函式模式

function SpecialArray() {
  var o = new Array()
  // 新增值
  o.push.apply(o,arguments)
  // 新增方法
  o.toPipedString = function(){
    return this.join('|')
  }
  return o
}
var o1 = new SpecialArray(1,11)
o1.toPipedString() // 1|11

優點:在不更改原始建構函式的情況下為物件新增特殊方法
缺點:返回的物件與建構函式以及建構函式的原型沒有任何關係,該方法與在建構函式外部建立的物件沒有什麼不同

穩妥建構函式模www.cppcns.com

function Person(name) {
  var o = new Object()
  // 新增方法
  o.getName = function(){
    return name
  }
  return o
}
var o1 = new Person(1)
o1.getName() // 1

與寄生建構函式不同在於,不使用this,不使用new呼叫
優點:除了使用getName外沒有任何方法能夠訪問name,在一些安全的環境使用
缺點:與工廠模式相似,無法識別物件所屬型別

以上就是js 建立物件的多種方式與優缺點小結的詳細內容,更多關於js 建立物件的資料請關注我們其它相關文章!